自定义标签在IE六-八的窘境

自定义标签在IE6-八的窘况

2015/07/20 · HTML5 ·
IE,
自定义标签

原稿出处:
司徒正美   

或许未来前端组件化之路都以自定义标签,但那东西早在20年前,JSTL已在搞了。现在Web
Component还唯有webkit辅助。但2个零件库,还须要三个卓越的标记它们是壹块的。但是这一个XML已经帮我们化解了,使用scopeName,如”<xxx:dialog>”。在自个儿继续往下想什么管理怎样为这些标签绑定数据,与其他零件通讯,管理生命周期,等等大事在此之前,小编还有一个只可以面对的主题材料,正是何许包容IE六-八!

诸如以下3个页面:

图片 1

在chrome, firefox, IE1一, IE1一的IE6包容方式分别如下:

图片 2
图片 3
图片 4
图片 5

我们会发觉IE陆下实际是多出过多标签,它是把闭标签也改为三个独立的成分节点

图片 6

以此AA:DIV标签被开膛破肚,里面子节点全体暴出来,成为其兄弟节点了。由此想包容它,就要费点劲。有个三个情形须求思量,1是用户已经将它写在页面上,景况同上;贰是用户是将它身处字符串模版中,这些用正则解决。但是正则假若冲击复杂的属性名,依旧会晕掉。因而小编照旧筹划动用原生的HTML
parser。换言之,字符串,作者也许会将它形成节点。这么办吧?!小编想了多数艺术,后来照旧使用VML的命名空间法消除!

我们将下边包车型地铁页面改复杂点,再看看效果!

图片 7
图片 8

能够见见其套嵌关系现在完全正确,并且标签字不会大写化,也不会转移多余节点!

好了,大家再决断一下是或不是为自定义标签,可能纯粹地说,这些节点是或不是大家组件库中定义的自定义标签。有个别境况下,2个页面能够存在多套组件库,包含avalon的,ploymer的,大概是间接用Web
Component写的。

avalon的机件库将选择命名空间,那样就好界别开。在IE陆-玖中,推断element.scopeName是还是不是为aa(那是组件库的命名空间,你可以改个更了不起上的名字),在其它浏览器决断此因素的localName是或不是以aa:初阶就行了!

JavaScript

function isWidget(el, uiName){ return el.scopeName ? el.scopeName ===
uiName: el.localName.indexOf(uiName+”:”) === 0 }

1
2
3
function isWidget(el, uiName){
  return   el.scopeName ? el.scopeName === uiName: el.localName.indexOf(uiName+":") === 0
}

其①难点化解后,大家就能够开搞基于自定义标签的UI库了!

1 赞 1 收藏
评论

图片 9

var arr = new Array();
if(xxx) {
   for(var i = 0,len = arr.length ; i < len; i++) {

   }
} else {
   for(var i = 0,len = arr.length ; i < len; i++) {

   }
}

H5扩展了HTMLDocument

       
写这么些库,首先利用了命名空间,笔者相比较欣赏toper,所以自个儿先是定义了一个变量:

二、包容情势

           
PS:使用了原生的document.getElementsByClassName的终将不受那一个影响的。

布置标志

     
 行吗,貌似又超时了,先就那样呢,感到每便写那种日志都会消耗数不完时光。

荒唐事件

其余未有经过try-catch处理的荒谬都会触发window对象的error事件

tp.event.preventDefault = function(event) {
        if(event.preventDefault) {
            event.preventDefault();
        } else {
            event.returnValue = false;
        }
    };
    tp.event.stopPropagation = function(event) {
        if(event.stopPropagation) {
            event.stopPropagation();
        } else {
            event.cancelBubble = true;
        }
    };

不当类型

Error

EvalError

RangeError

ReferenceError

SyntaxError     //语法错误

TypeError        //类型错误

URIError

Error是基类,别的品种都接二连三自该类,全数错误类型共享同一组属性

伊娃lError在应用eval是抛出,轻巧说,正是未有把eval当函数用,就抛出荒唐

RangeError在数值高于相应范围时接触

var item = new Array(-20);     //触发
var item = new Array(Number.MAX_VALUE);     //触发

找不到对象,产生ReferenceError

变量保存意外类型,访问不设有的秘籍,都会抛出TypeError

var o = new 10;
alert("name" in true);
Function.prototype.toString.call("name");
//以上都会抛出TypeError

encodeURubiconI,decodeU汉兰达I,会抛出U福睿斯IError,少见,这两货的容错性高

境遇throw操作符,代码立时终止执行

throw 1234;
throw "hello";
throw true;
throw {name:"js"};
//以上代码都是有效的

还是能够创制自定义错误新闻:

throw new Error("some message");
throw new SyntaxError("syntax error");
throw new ReferenceError("reference error");

还能够够创建自定义错误类型:(通过承继Error)

function CustomError(message){
     this.name = "CustomError";
     this.message = message;
}
CustomError.prototype = new Error();
throw new CustomError("my message");

         
 那样,整个推断只供给施行1遍,前面调用的时候只须求选拔_add伊芙ntListener就能够,当然,由于选择了闭包,tp.event命名空间之外是不足访问那多少个函数的。

肆、内部存款和储蓄器质量难点

动用上述的形式也许导致浏览器内部存款和储蓄器占用难点。调用方法是,最棒手工删除被交换来分的有所事件管理程序

注:尽量收缩innerHTML和outerHTML的次数,压缩使用

例:

for(var i = 0, len = values.length;i < len; i++){
     ul.innerHTML += "<li>"+values[i] +"</li>";          //要访问两次innerHTML,一次读,一次写,渣渣的性能
}
//改进版本:
var item = "";
for(var i = 0, len = values.length;i < len; i++){
     item += "<li>"+values[i] +"</li>";                  //构建HTML字符串
}
ul.innerHTML = item;                                     //只进行一次调用,一定程度上提高了性能
document.documentMode;                                   //返回给定页面使用的文档模式的版本号

contains方法:接收两个参数,要检验的节点,重临调用此方法的节点是或不是含有检查评定节点

支持的浏览器IE,Safari,Firefox玖+,Chrome,Opera。

DOM Level 三compareDocumentPosition方法也得以鲜明节点间事关,帮忙浏览器IE九+,Safari,Firefox,Chrome,Opera9.伍+。再次回到用于表示多个节点间的涉及的位掩码

掩码

节点关系

1

无关,给定节点不在当前文档中

2

居前

4

居后

8

包含

16

被包含

        然后正是浏览器判别,笔者是那样写的:

querySelectorAll方法

与querySelector接收一样的参数,不过回到的是叁个NodeList实例,具体点正是,再次来到的值实际上是含有全数属性和办法的 NodeList。

与querySelector类似,能够调用querySelectorAll的品类包蕴Document、DocumentFragment、Element

例:

//取得某<div>中所有<em>元素(类似getElementsByTagName("em"))
var ems = document.getElementById("myDiv").querySelectorAll("em");
//取得类为"selected"的所有元素
var selecteds = document.querySelectorAll(".selectored");
//取得所有<p>元素中的所有<strong>元素
var strongs = document.querySelectorAll("p strong");

要获取重返的NodeList的成分,能够采取item方法或方括号法

注:传入不被帮衬的挑选符会抛出错误

Selector API
Level2
规范为Element类型新添了1个形式matchesSelector,接收四个参数,CSS选择符,若调用成分与该采纳符相称再次来到true,不然再次来到false

注:到201一年年中还尚未浏览器援救此办法,但是,IE玖+通过msMatchesSelector,Firefox三.6+通过mozMatchesSelector,Safari伍+和Chrome通过webkitMatchesSelector协理该形式

tp.event.getTarget = function(event) {
        return event.target || event.srcElement;
    };

2、Document类型变化

蕴涵下列与命名空间有关的主意:

createElementNS(namespaceU中华VI,tagName):使用给定的tagName创造1个属于命名空间namespaceU奥德赛I的新因素

createAttributeNS(namespaceU帕杰罗I,attributeName):使用给定的attributeName创制一个属于命名空间namespaceURubiconI的新天性

getElementsByTagNameNS(namespaceU普拉多I,tagName):再次来到属于命名空间namespaceUQashqaiI的tagName成分的NodeList

例:

//创建一个新的svg元素
var svg = document.createElementNS("http://www.w3.org/2000/svg","svg");
//创建一个属于某个命名空间的新特性
var att = document.createAttributeNS("http://www.somewhere.com","random");
//取得所有XHTML元素
var elems = document.getElementsByTagNameNS("http://www.w3.org/1999/xhtml","*");

注:唯有在文书档案中设有四个命名空间的时候,那一个与命名空间有关的措施展才能是须要的

  

调解才具

将音信记录到调控台

将错误音信记录到目前页面

抛出荒谬

           我认为:#aa
input那种实际上正是经过document.getElementById查询之后然后查询它的子孙节点中的全数满足tagName为input的因素;而#aaa
>
input那种正是查询它的孩子节点中是或不是有这种满意条件的成分。以往全部流程相比简单了,对于一个错综复杂查询,首先举办一个简易询问,然后按照查询的结果集结,举办一遍遍历,对各种节点查询它的男女节点或子孙节点,将装有知足条件的放入到别的三个数组,假设该数组为空,那么直接回到空数组,不然,继续开始展览下3回查询(依然查询孩子节点或子孙节点)。

TreeWalker

NodeIterator的越来越高级版本除了NodeIterator的多少个艺术外,还提供用于在分裂倾向遍历DOM的不二等秘书技:

parentNode():遍历到目前节点父节点

firstChild():到当下节点的第一个头节点

lastChild():到当下节点的尾声3个子节点

nextSibling():到眼下节点的下3个同辈节点

previousSibling():到近期节点的上贰个同辈节点

选用document.createTree沃克方法,与document.createNodeIterator类似接收肆各参数:根节点,要出示的节点类型,过滤器,是不是扩张实体引用布尔值

不同:filter返回值:除了 NodeFilter.FILTER_ACCEPT,NodeFilter.FILTER_SKIP,还有NodeFilter.FILTER_REJECT,NodeFilter.FILTER_SKIP会进入子节点搜索,而NodeFilter.FILTE奥迪Q7_REJECT则跳过任何子节点树,剪枝算法

TreeWalker类型还有3个性格:currentNode,通过改变此属性还是能改造搜索源点

          除了DOM,对变量类型的判定和浏览器的检查测试也是很注重的。

4、框架变化

define("tp.a",["tp.c","tp.d"],function(c,d) {
   tp.modules.add("tp.a",function() {

    });
});

3、insertAdjacentHTML方法

收下五个参数:要插入的任务,要插入的HTML文本,第三个参数必须是下列值之1

“beforebegin”,在当下因素以前插入紧邻的同辈成分

“afterbegin”,在现阶段成分插入2个新的子元素或在首先个子成分在此以前插入新的子元素

“beforeend”,在当下成分以下插入2个新的子成分或在结尾1个子元素之后插入新的子成分

“afterend”,在现阶段成分之后插入一个同辈成分

       
小编看了一下,不一样的库的决断情势不等同,小编那时使用的是tangram的判断格局。

NodeIterator类型

能够应用document.createNodeIterator方法创制实例,接收四个参数:root(起点),whatToShow(要拜访的节点的数字代码),filter(NodeFilter对象,或意味着应该接受或拒绝某种特定节点的函数),entityReferenceExpansion(布尔值,是不是要庞大实体引用)

whatToShow是2个掩位码,以常量形式在NodeFilter类型中定义

NodeFilter.SHOW_ALL:显示全体

NodeFilter.SHOW_ELEMENT:展现成分节点

NodeFilter.SHOW_ATT福睿斯IBUTE:性子节点,由于DOM结构原因,实际上,这么些值不能够动用

NodeFilter.SHOW_TEXT:文本节点

NodeFilter.SHOW_CDATA_SECTION:显示CDATA节点,对HTML没用

NodeFilter.SHOW_ENTITY_REFERENCE:实体引用节点,对HTML没用

NodeFilter.SHOW_ENTITYE:实体节点,对HTML没用

NodeFilter.SHOW_PROCESSING_INSTRUCTION:管理指重三点,对HTML没用

NodeFilter.SHOW_COMMENT:注释节点

NodeFilter.SHOW_DOCUMENT:文书档案节点

NodeFilter.SHOW_DOCUMENT_TYPE:文书档案类型节点

NodeFilter.SHOW_DOCUMENT_FRA克拉霉素ENT:文书档案片段节点,对HTML没用

NodeFilter.SHOW_NOTATION:符号节点,同上

除NodeFilter.SHOW_ALL外,能够使用按位或操作符组合四个挑选

每一种NodeFilter对象只有一个方法:acceptNode(),重回NodeFilter.FILTELX570_ACCEPT或者NodeFilter.FILTER_SKIP,NodeFilter是贰个华而不实类型,不能直接创设实例,须要时得以创设3个含有accpetNode方法的靶子,传入createNodeIterator就能够

例:

var filter = {
    acceptNode:function(node){
        return node.tagName.toLowerCase() == "p" ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
    }
};
var iterator = document.createNodeIterator(root,NodeFilter.SHOW_ELEMENT,filter,false);
//或者使用一个与acceptNode方法类似的函数
var filter = function(node){
    return node.tagName.toLowerCase() == "p" ?
            NodeFilter.FILTER_ACCEPT :
            NodeFilter.FILTER_SKIP;
};

NodeIterator类型三个首要方法:nextNode(),previousNode()

         
 除了事件监听器,还索要事件风云的丰盛,删除等,相当于add,fire,remove等,这里就不说了。

第11章, DOM扩展

          我此时写了二个扶植函数:

检查测试浏览器是还是不是帮忙DOM模块:

var supportsDOM2Core = document.implementation.hasFeature("Core","2.0");
var supportsDOM3Core = document.implementation.hasFeature("Core","3.0");
var supportsDOM2HTML = document.implementation.hasFeature("HTML","2.0");
var supportsDOM2Views = document.implementation.hasFeature("Views","2.0");
var supportsDOM2XML = document.implementation.hasFeature("XML","2.0");

     
 当然,还有浏览器版本的决断,临时就不贴出来了。那里基本思路正是推断navigator.useAgent重临的字符串中,每一个浏览器里面包车型地铁那个字符串是不一样样的,当然,那么些进度比较恶心,而且有十分的大可能率后边某三个浏览器会改造它的userAgent,导致整个判别失效,比方IE,听别人说前面新IE要把userAgent搞成firefox,真心搞不懂,那是要逆天啊?

1、innerText

<div id="content">
     <p>This is a <strong>paragraph</strong> with a list following it.</p>
     <ul>
          <li>Item 1</li>
          <li>Item 2</li>
          <li>Item 3</li>
     </ul>
</div>

对<div>元素来讲innerText再次回到:(不自然带有原始代码的缩进)

This is a paragraph with a list following it. 

Item 1 

Item 2 

Item 3

使用innerText设置:

div.innerText = "hello world!";

结果:

<div id="content">hello world!</div>

注:innerText也会对文本中的HTML语法字符(>,<,”,&)进行编码

支撑的浏览器IE4+,Safari3+,Chrome,Opera八+。Firefox不援助,但支撑类似属性textContent属性,textContent是DOM
Level 三规定的二天性质,IE玖+,Safari三+,Chrome,Opera十+也帮忙textContent

         
感到JS的包容性真心很头疼啊,就比方在DOM那1道,为了协作,我都做了相当长日子。当然,DOM这壹块儿毫无疑问不止这么一点剧情,临时也不写了。

HTML5

H5新增添了许多API,致力于简化CSS类的用法

         
常用的职能自然照旧阻止事件冒泡以及阻碍暗中同意事件的产生,很遗憾,IE和非IE管理格局照旧不平等的,举个例子阻止冒泡IE选用的是cancelBubble,而任何浏览器选用的是stopPropagation,所以依然须求写:

要害管理

document.activeElement属性,始终获得当前DOM得到了关键的因素,成分获得主旨格局:页面加载,用户输入(日常经过tab),代码中调节focus方法。

文书档案刚加载完,document.activeElement保存document.body,加载时期为null

document。hasFocus方法,显明文书档案是不是获得主题

落成那两本天性浏览器IE4+,Firefox三+,Safari四+,Chrome,Opera八+

           所以,在每一种查询的最开头,供给将传递的查询格式化,比如#aa
>input那种格式化为:#aa >
input,多个空格变为一个空格,>两边必须有1个空格等。

遍历

DOM二级遍历和限制定义了逐3次历DOM结构的项目:NodeIterator,Tree沃克,那两个品类推行深度优先遍历(深搜)

     
然后就是事件了,事件是二个对比恼火的事务,东西相比多,笔者把它坐落了tp.event那些空间中。

IE⑧及更早版本中的范围

IE八及更早版本并不帮助DOM范围(IE便是那样拽),支持类似概念文本范围

       
 #aa那种比较轻便,因为JS提供了API,也正是document.getElementById;input那种也相比好搞,因为JS有document.getElementsByTagName;然而.aa那种艺术就相比纠结了,因为JS未有提供API,幸而,在部分浏览器中还是提供了API:document.getElementsByClassName,而那么些未有提供这些API的就相比较喜剧了,只可以遍历全体节点,也等于采纳document.getElementsByTagName(*):

常见IE错误(IE,最难调节和测试js错误的浏览器,难怪那么拽)

操作终止

失效字符

未找到成员

不解运行时不当

语法错误

系统不能够找到钦点财富

           作者把每3个查询如:tp.dom.query(“#aa
input”)分为二种,1种为简便询问(也正是如查询:#aaa),此外一种是扑朔迷离查询,种种复杂查询都以由多数简练询问构成的,比如#aaa
input,就足以切成:#aaa和input。

其他变化

     
作者使用的结构是core+组件的方式,tp.core.js(压缩后为tp.core-min.js),而其余的零件每一个组件八个文本,而组件之间大概存在依赖关系,那种借助关系就通过英特尔消除。

3、head属性

H伍新添document.head属性,拿到<head>成分,扶助浏览器Chrome,Safari五+

发表评论

电子邮件地址不会被公开。 必填项已用*标注