【亚洲必赢官网】组件化的Web王国,自定义标签在IE6

自定义标签在IE6-8的泥沼

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

原文出处:
司徒正美   

想必未来前端组件化之路都是自定义标签,但那东西早在20年前,JSTL已在搞了。现在Web
Component还唯有webkit协理。但一个零部件库,还必要一个例外的标识它们是一块的。可是这些XML已经帮大家搞定了,使用scopeName,如”<xxx:dialog>”。在自身继续往下想什么处理怎么样为这一个标签绑定数据,与任何零件通讯,管理生命周期,等等大事从前,我还有一个不得不面对的题材,就是何等包容IE6-8!

诸如以下一个页面:

亚洲必赢官网 1

在chrome, firefox, IE11, IE11的IE6包容格局分别如下:

亚洲必赢官网 2
亚洲必赢官网 3
亚洲必赢官网 4
亚洲必赢官网 5

大家会意识IE6下实际是多出众多标签,它是把闭标签也改为一个单身的元素节点

亚洲必赢官网 6

以此AA:DIV标签被开膛破肚,里面子节点全部暴出来,成为其兄弟节点了。由此想包容它,就要费点劲。有个五个情景须要考虑,1是用户已经将它写在页面上,情状同上;2是用户是将它放在字符串模版中,那些用正则搞定。但是正则若是碰撞复杂的属性名,照旧会晕掉。由此我依然打算利用原生的HTML
parser。换言之,字符串,我依旧会将它成为节点。这么办吧?!我想了好多方法,后来依旧利用VML的命名空间法搞定!

咱俩将地方的页面改复杂点,再看看效果!

亚洲必赢官网 7
亚洲必赢官网 8

可以看看其套嵌关系现在完全正确,并且标签名不会大写化,也不会转移多余节点!

好了,大家再判定一下是还是不是为自定义标签,或者纯粹地说,那几个节点是还是不是大家组件库中定义的自定义标签。某些情形下,一个页面可以存在多套组件库,包含avalon的,ploymer的,或者是一贯用Web
Component写的。

avalon的组件库将接纳命名空间,那样就好界别开。在IE6-9中,判定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

     
 还记得自己大二的时候先导接触JS,那个时候从体育场馆借了N多的书本,然后面看边用editplus写,然后蒙受问题,各样DEBUG,在做项目标时候,种种包容性问题,真是痛心啊。由于种类必要赶紧写完,所以就起来接触了jquery,依然从教室抱了几本书,然后下载了jquery源码,然后面看书籍边写代码,看了几章之后,觉得貌似不难,然后就从网上下载了jquery的文档,对照着文档,对其调用搞获得底相比清楚了。

第11章, DOM扩展

本文由 埃姆杰 翻译。未经许可,禁止转发! 英文出处:Future Insights。

       
现在总的来说,我觉着学习jquery反而使自己走了弯路,用jquery是比较方便,也休想考虑包容性问题了,而且调用非常简单优雅,不过,反而我对原生js感觉更是陌生了,也造成了背后感觉完全离不开jquery了,想去写一个XXX组件,想了一晃,思路有了,然后写的时候蒙受各类问题,然后就又赶回jquery了。

选择符 API

Selector API
Level1
骨干措施querySelector 、querySelectorAll,包容的浏览器可以动用 Document,Element 实例调用它们,帮忙浏览器:IE8+,Firefox3.5+,Safari3.1+,chrome,Opera10+

内容提要

行使过多独门组件构建应用程序的想法并不新鲜。Web
Component的产出,是再度回想基于组件的应用程序开发情势的好机遇。大家可以从那几个进程中受益,明白什么行使现有技术成功目的,并且在未来做出自己的前端Web应用。

       
 从上年暑假的时候,我说了算离开jquery了,jquery是一把双刃剑,开发的时候是便宜,但是,作为一个初学者,我以为那是很不利的。

querySelector方法

接受一个 CSS选取符,重回与该格局匹配的率先个要素

因而 Document类型调用该函数,会在文档范围查找匹配元素,通过 Element类型调用该函数,只会在该因素后代范围内寻找

注:传入不被协助的选拔符会抛出荒谬

例:

//取得body 元素
var body = document.querySelector(“body”);
//取得ID 为”myDiv”的元素
var myDiv = document.querySelector(“#myDiv”);
//取得类为”selected” 的第一个元素
var selected = document.querySelector(“.selected”);
//取得类为”button” 的第一个图像元素
var img = document.querySelector(“img.button”);

哪些是组件?

软件开发是一个语义丰硕(术语寻常持续一个意思)的圈子。很显眼,那里的“组件”是一个很泛的号称,所以有必不可少指明我们想要表明的,在前端Web应用的语言环境中的意思。

前端Web应用中的组件,是指部分统筹为通用性的,用来构建较大型应用程序的软件,那一个零件有多种表现格局。它可以是有UI(用户界面)的,也得以是用作
“服务”的纯逻辑代码。

因为有视觉上的表现方式,UI组件更易于了然。UI组件简单的事例包罗按钮、输入框和文本域。不论是布达佩斯包状的菜系按钮(无论你是否喜欢)、标签页、日历、选项菜单或者所见即所得的富文本编辑器则是部分尤其高档的事例。

提供服务类型的零部件可能会令人难以明白,那系列型的例子包含跨浏览器的AJAX帮忙,日志记录或者提供某种数据持久化的效用。

基于组件开发,最要害的就是组件能够用来整合任何零件,而富文本编辑器就是个很好的事例。它是由按钮、下拉菜单和一部分可视化组件等组成。另一个例子是HTML5上的video元素。它一律含有按钮,也还要含有一个能从视频数据流渲染内容的因素。

       
 然后就从头下载JS的电子书,可能是协调相比较躁动吧,看书真心看不进来,我仍旧喜欢边看边写代码那种。写了一段时间,逐步的认为起头河的感觉到逐渐回来了,当然,也碰着了N多的题目。

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类型新增了一个办法matchesSelector,接收一个参数,CSS选用符,若调用元素与该接纳符匹配再次来到true,否则再次来到false

注:到二〇一一年年中还没有浏览器协助此方法,然而,IE9+通过msMatchesSelector,Firefox3.6+通过mozMatchesSelector,Safari5+和Chrome通过webkitMatchesSelector支持该措施

怎么要构建组件?

既然现在一度知道组件的情趣,就看看使用组件的章程构建前端接纳的益处。

       
到寒假的时候,决定自己的毕设不使用现在成熟的JS库,反而自己来写一个不完善的库,那样学习的越多,当然,也相比较费时间。

装进该办法代码:

function matchesSelector(element,selecrot){
     if(element.matchesSelector){
          return element.matchesSelector(selector);
     }else if(element.msMatchesSelector){
          return element.msMatchesSelector(selector);
     }else if(element.mozMatchesSelector){
          return element.mozMatchesSelector(selector);
     }else if(element.webkitMatchesSelector){
          return element.webkitMatchesSelector(selector);
     }else {
          throw new Error("Not supported");
     }
}
if(matchesSelector(document.body,"body.page1")){
     //操作
}

模块

你可能听说过 “组件是后天性模块”的传教。好吧,感谢它,大家又要表达这里的术语!

你可能会认为“组件”的传教更为符合用来叙述UI,而“模块”更适合描述提供劳务的意义逻辑。而对此我来说,模块和组件意思相近,都提供团体、聚焦和包装,是与某个意义单位有关的。

       
先导写的感觉到真是优伤啊,什么都不懂,所以就去看了看tangram的源码,为啥看tangram呢,其实原因相比较搞笑,当时校招的时候我面试百度前端,被刷掉了,当时面试官让自己看看它们百度应用的JS库tangram,我就想看看它们极度库到底有怎么着了不起的。。。

要素遍历

对于元素间空格,IE9及前面并不会回到文本节点,其余浏览器都会,为此Element
Traversal规范新定义属性:

childElementCount:再次回到子元素个数,不包蕴文件节点和注释

firstElementChild:firstChild元素版

lastElementChild:lastChild元素版

previousElementSibling:previousSibling元素版

nextElementSibling:nextSibling元素版

运用上述因素得以不用顾虑空白文本节点

支撑Element Traversal规范的浏览器IE9+,Firefox3.5+,Safari4+,Chrome和Opera10+

高内聚

又是一个软件工程的高频词! 我们将相关的一对功力团体在共同,把任何封装起来,而在组件的例子中,就可能是连锁的功用逻辑和静态资源:JavaScript、HTML、CSS以及图像等。那就是大家所说的内聚。

那种做法将让组件更便于保险,并且这么做之后,组件的可相信性也将增加。同时,它也能让组件的功力分明,增大组件重用的可能性。

       
写这么些库,首先选取了命名空间,我比较喜欢toper,所以我先是定义了一个变量:

HTML5

H5新增了不少API,致力于简化CSS类的用法

可重用

您看看的演示组件,尤其是Web
Component,更关切可采纳的题材。成效显明,完毕清晰,API易于了解。自然就能促进组件复用。通过构建可拔取组件,大家不但有限支撑了 DRY(不要再一次造轮子)规范,还获得了对应的益处。

那边要提示: 不要过于尝试构建可选择组件。你更应该关注应用程序上所必要的这个特定部分。倘若未来相应必要应运而生,或者零部件的确到了可选用的程度,就花一点万分时间让组件重用。事实上,开发者都喜爱去创立可选拔功用块(库、组件、模块、插件等),做得太早将会让您后来痛楚不堪。所以,吸取基于组件开发的此外利益,并且接受不是有所组件都能重用的真实情形。

var tp = tp || {};

1、getElementsByClassName方法

document及具备HTML元素都足以调用该方式

此办法接收一个参数,包涵一个或八个类名的字符串,重临带有指定类的具备因素构成的NodeList

//取得所有类中包含"username"和"current"的元素,类名先后顺序无关
var allCurrentUsernames = document.getElementsByClassName("username current");
//取得ID为"myDiv"的元素中所有类名"selected"的所有元素
var selected = document.getElementById("myDiv").getElementsByClassName("selected");

在要素上调用,只会回来后代元素中的匹配,在document上调用,重回所有

注:因为再次来到的是NodeList,所以,会设有与所有再次回到NodeList的格局同样的性质问题

协理的浏览器IE9+,Safari3.1+,Firefox3+,Chrome,Opera9.5+

可互换

一个功力分明好组件的API能让人随意地改变其中间的作用完成。如若程序内部的组件是松耦合的,那实在可以用一个零部件轻易地更迭另一个零件,只要根据相同的 API/接口/约定。

一旦你选拔GoInstant提供的实时效应劳务组件,那她们下周关门服务如此那般的消息会影响到您。但是,只要提供了相同的数目同步API,你也得以活动构建利用一个 FirebaseComponent 组件或者 PubNubComponent 组件。

       
这种方法也是借鉴了tangram的写法,采纳对象字面量的花样。这样有着toper定义的主意都置身了tp那几个私有空间内了,比如对DOM的操作就放在tp.dom中。

2、classList属性

H5为所有因素添加了classList属性,是新集合类型DOMTokenList的实例。DOMTokenList有length属性,可以因而item方法和方括号法访问元素,其余定义的方法:

add(value):将加以的字符串值添加到列表中,已存在不添加

contains(value):列表是还是不是存在给定值,是,重回true,否,再次来到false

remove(value):移除给定字符串

toggle(value):列表若已存在,移除,不设有,添加

例:

<div class="bd user disabled">..</div>
//删除"disabled"类
div.classList.remove("disabled");
//切换"user"类
div.classList.toggle("user");

可组合

事先也商量过,基于组件的架构让组件组合成新组件更加简单。那样的统筹让组件越发注意,也让其余零件中构建和暴光的意义更好使用。

任凭是给程序添加效果,照旧用来制作完整的先后,尤其错综复杂的成效也能萧规曹随。那就是那种措施的机要利益。

【亚洲必赢官网】组件化的Web王国,自定义标签在IE6。是还是不是有要求把装有的事物转换成组件,事实上取决于你自己。没有任何理由让你的先后由 你自己 的组件组合成你最惊叹的功能 ,乃至 最花哨的功能。而那么些零件又反过来构成任何零件。即便你从那一个格局中得到了功利,就想法地去锲而不舍它。不过要注意的是,不要用同样的主意把作业变得复杂,你并不须要过分关切怎样让组件重用。而是要关爱突显程序的成效。

     
 由于那一个库完全是为毕设做的,所以那其间的累累文本都是为促成毕设的一点功用而写的。

节骨眼管理

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

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

document。hasFocus方法,确定文档是不是得到大旨

落到实处那多少个属性浏览器IE4+,Firefox3+,Safari4+,Chrome,Opera8+

今昔就从头构建组件

在 Caplin
Systems 构建基于组件的自有应用程序时,我动用了几条原则和执行。那个标准由 BladeRunnerJS(BRJS) 开源工具集支撑。它被称作”BladeRunnerJS”
是因为我们将次第功用都封装在称作 Blades 的事物中。Blade是足以在某个应用中选定的功力特色,但是不可以在程序间重用。当效用真的
变得更其通用的时候,我们将相应的定义移到库文件中,供各个程序间选拔。特定应用中的组件(blade)和我们先后间的通用组件可以运用,大家假如找到最好满意须要的任何库和框架。

那么,现在怎么样库和框架可以支持我们构建组件呢?

在支配构建利用时应拔取何种技术时,只须求探视流行的 TodoMVC 网站就可以看出大批量可供接纳的前端库和框架。你或许会认为任何一种方案都能用来构建基于组件的应用程序。不过,他们之中的局地方案内置了对组件的辅助。其中相比较知名的是AngularJS、Ember
和 React。

     
我动用的构造是core+组件的办法,tp.core.js(压缩后为tp.core-min.js),而别的的组件每个组件一个文书,而组件之间或者存在依靠关系,那种看重关系就通过英特尔解决。

H5扩展了HTMLDocument

组件间是什么样通讯的?

在深刻示例此前有要求不难地关系组件间通讯的题材。要是组件之间是“独立”、“模块化”的,他们又是何许相互通讯的呢?

最分明的答案就是让组件间互为引用并由此她们中间的API交互。那样做的题材就在于,那种做法会让组件相互看重。短时间内或者还好,一段时间将来,你在修改程序的时候程序会失控,修改一个零件就会对另一个零件爆发巨大的熏陶。决定移除一个不可以带来预期价值组件可能会让您的应用程序为止工作,因为它背后会有数个零件看重于它。

此刻,解决方案是提供松耦合的,让组件之间很少如故大致不明白相互的方案。组件并不直接成立其他零件,在她们要求通讯的时候,他们经过“接口/约定”或者通过 “服务”。大家在构建BRJS程序时考虑了重重这一个方面的事物,并且利用 ServiceRegistry 访问用于组件间通讯的劳务依然是Web
API这么的资源。Angular和Ember采取了劳务和借助注入解决那类问题。

     
在未曾写这些库之前,就算是本身使用jquery,每一个JS文件我都是平昔在HTML文件中动用script标签写进去的,而前日内需选取那种异步模块加载的法子,假诺要使用非主旨模块,那么须要:

1、readyState属性

值:loading –>
正在加载,complete –> 加载完成

支撑的浏览器IE4+,Firefox3.6+,Safari,Chrome,Opera9+

以身作则组件my-avatar

为了显得我们怎么用那么些库和框架构建最基本的组件,大家树立了一个涵盖UI,用于取回和显示用户头像的粗略示例。在可能的景色下,该器件会有 my-avatar 标签,会从以下四个属性中获得头像:

  • service 允许设置一个服务。例如 twitter 或者 facebook
  • username 用于取回该用户名相对应的头像
tp.use(["tp.a","tp.b"],function(a,b) {

})

2、包容情势

AngularJS

AngularJS 可能是今天用于构建程序最风靡的前端解决方案了。作为创小编的Google,重新思考HTML,考虑怎么样重新发明,满意近期Web开发的内需。

Angular中得以利用自定义指令概念组件。之后,你可以行使 HTML
标记注明自定义组件。

翻看代码演示: 

其一例子显示了利用Angular指令的简短程度。值scope 定义了从
 my-avatar 元素中拿走,并且之后用来构建相应的img标签和渲染成用户头像的习性。

     
使用use形式,它会活动去下载tp.a.js和tp.b.js,下载完毕将来,执行回调函数。

3、head属性

H5新增document.head属性,得到<head>元素,支持浏览器Chrome,Safari5+

Ember

框架与库的争议旷日持久,总的来说框架是强制你按某种格局做事情,所以它是穷凶极恶的。很明朗,Angular是个框架,而Ember的作者,Yehuda
Katz和汤姆(Tom)Dale也很乐意把Ember看作框架。

Ember 有对它称为组件的内建接济。Ember
Components背后的理念是不择手段的向Web
Components看齐,当浏览器扶助允许时,就可以很便利地迁移到Web
Components中。

翻开代码演示: 

上面的事例中使用了 handlebars 做模板,所以元素的概念不是一样种语法。

      同样,在tp.a.js中,也无法运用普通的JS的写法了,而要使用:

字符集属性

H5新增charset属性,表示文档实际运用字符集,可更改,接济浏览器IE,Safari,Chrome,Opera。Firefox帮忙Characterset

defaultCharset属性,表示根据默许浏览器和操作系统设置,确定用什么字符集,援助浏览器IE,Safari,Chrome

能够自定义非标准属性,要添加前缀data-,dataset属性可以访问,dataset是DOMStringMap的实例

React

React 即使是个新人,然而却一度有好多的维护者。它由脸谱开发,并且已经到家用于Instagram的UI和局地脸书的UI。

拔取React构建组件的引荐方法是选拔叫做 JSX 的事物来定义它们。那是一种“推荐在React上使用的JavaScript语法转换”。请不要就此分心。他们曾经在文档中指出,这几个想法就是用来支持您在JavaScript中写出HTML标记的。

本身不是说您并不得以向来在HTML中添加标签,而必须选取JSX创制自己的零部件。不过,只要你定义了一个零件,你就足以应用这么些组件创制其余零件。

翻开代码演示: 

由此,组件使用的宣示语法须要相应的HTML元素和对 React.RenderComponent 的调用。

 

部署标记

未来:Web Component和其他

Web
Component才是鹏程!正如名字所表示的那么,他们承诺将牵动能够将功效封装成组件的浏览器原生支持。

自己将简单浮现Web
Component并且演示我们前天可以怎么利用它。尤其心心念念的始末请参考本文末尾的 “外部资源” 一节。

他俩提供的功用包含:

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

    });
});

1、innerHTML属性

读模式,再次来到与调用元素的所有子节点对应的HTML标记,包蕴属性,注释,文本节点

写方式,按照指定值创设DOM树,然后用那个DOM树替换原先所有子节点

注:设置的HTML字符串,会通过分析

注:限制:在大部浏览器中经过此属性插入<script>元素并不会进行其中的剧本,IE8及更早版本可以,条件还挺多

不帮助此属性的要素:<col>,<colgroup>,<frameset>,<head>,<html>,<style>,<table>,<tbody>,<thead>,<tfoot>,<tr>,在IE8及更早浏览器<title>也向来不

自定义元素

俺们在上边关心的是用Angular、Ember和React构建 my-avatar 的事例。可能的情况下,那样的章程将以页面上或者模板上添加的自定义元素表示。Web
Component包蕴透过自定义元素赢得的原生匡助– 相对是Web Component标准的中坚组成部分。

概念新元素,包罗走访元素生命周期的有的事件例如曾几何时成立(createdCallback)、什么时候添加在DOM树上(attachedCallback)、何时从DOM树上分离(detachedCallback),什么日期元素属性改变(attributeChangedCallback(attrName, oldVal, newVal))。

自定义元素的一个重大的局地就是有能力从原来元素增添,由此得到原有元素相应的效率。示例中我们扩张了 <img>元素 。

终极,我们所写的代码中,自定义元素正在并且倾向去做的就是将复杂的东西抽象化,让用户关注于单个组件暴发的价值,从而用来构建尤其助长的意义。

   
 define的首先个参数是该器件的名字(需求唯一,所以我照旧依据命名空间的措施写的),第一个参数是这一个组件所依赖的零件,第多个参数是回调函数,也就是当依赖的组件下载完毕之后,回调执行,而tp.modules.add就足以将那么些模块加载到全体库中,这样的话才能选拔tp.use调用。

2、outerHTML属性

读格局,再次来到与调用元素的所有子节点对应的HTML标记

写形式,按照指定值成立DOM树,然后用那些DOM树替换原先元素

支撑的浏览器IE4+,Safari4+,Chrome,Opera8+。Firefox7及前边版本都不辅助

Shadow DOM

还记得iframe们吧?大家还在动用它们,是因为她俩能保险组件和控件的JavaScript和CSS不会影响页面。 Shadow
DOM 也能提供那样的爱戴,并且没有iframe带来的承担。正式的传教是:

Shadow
DOM的陈设是在shadow根下隐藏DOM子树从而提供包装机制。它提供了建立和有限协助DOM树之间的功用界限,以及给那么些树提供互相的功能,从而在DOM树上提供了更好的功效封装。

     
那种方法本身在tangram中没有观看,我是看了Taobao的KISSY之后读书到的,也就是所谓的英特尔(异步模块定义)。

3、insertAdjacentHTML方法

接到七个参数:要插入的职责,要插入的HTML文本,第四个参数必须是下列值之一

“beforebegin”,在现阶段元素此前插入紧邻的同辈元素

“afterbegin”,在当前因素插入一个新的子元素或在首先个子元素此前插入新的子元素

“beforeend”,在时下因素以下插入一个新的子元素或在最后一个子元素之后插入新的子元素

“afterend”,在眼前元素之后插入一个同辈元素

HTML导入

咱俩长日子在此从前就可以导入JavaScript和CSS了。 HTML导入成效提供了从其余HTML文档中导入和重用HTML文档的力量。那种简单性同时代表可以很便宜地用有些组件构建另一些零部件。

最后,那样的格式很美丽,适合可选取组件,并且能够用你最喜爱的包管了然决方案公布(例如: bower、 npm 或者 Component)。

     
暂时英特尔的贯彻格局是由此setInterval,可是即将被重构亚洲必赢官网 10

4、内存性能问题

采取上述的法门恐怕导致浏览器内存占用问题。调用方法是,最好手工删除被替换元素的保有事件处理程序

注:尽量裁减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,Firefox9+,Chrome,Opera。

DOM Level 3
compareDocumentPosition方法也得以规定节点间事关,协理浏览器IE9+,Safari,Firefox,Chrome,Opera9.5+。再次来到用于表示五个节点间的涉及的位掩码

掩码

节点关系

1

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

2

居前

4

居后

8

包含

16

被包含

模板

咱俩中的许三个人曾经应用像handlebars、mustache或者underscore.js中的模板那样的缓解方案(似乎大家在下边的Ember示例中用的一模一样)。Web
Component通过 template元素 提供了模版的原生接济。

原生模板让你可以申明分类为“隐藏DOM”然而解析成HTML的符号片段。他们在页面加载时没有用处,可是足以在运行时实例化。他们得以
被搜寻到 ,不过在插入活动的DOM树前不会加载任何有关资源。

     
我事先写了一篇日记来落到实处AMD,当然,作用低下,反正我们看看就行了

安排文本

不曾纳入H5规范的属性

Platform.js

只是,就像是每回提到新特色一样,大家不可以确定浏览器是或不是帮衬那一个特征。

亚洲必赢官网 11

以至于二〇一四年6月27日,Web Component 的浏览器帮助情形

相同,我们也能经过一些神奇的匹配代码,先河运用一些Web
Component所提供的功能。

亚洲必赢官网 12

有了包容库的Web Component协助情形

好新闻是三个先导进的浏览器厂商谷歌和Mozilla正在全力健全包容库
,帮忙大家选拔Web Component。

以下示例浮现使用platform.js后大家得以什么定义作为img元素伸张的my-avatar元素。最棒的是它能用到原生img元素的享有成效。

翻开代码演示: 

点击 HTML5 Rocks Custom Elements
tutorial 以查看创造自定义元素的更加多音信。

注:倘使你对platform.js感兴趣,也足以看看 bosonic。

原生技术的支持目标就是给大家提供相应的构建基础。所以Web
Component并不是库和框架的末尾信号。

     
然后就是事件了,事件是一个比较恼火的事务,东西相比较多,我把它置身了tp.event这几个空间中。

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,Opera8+。Firefox不帮忙,但接济类似属性textContent属性,textContent是DOM
Level 3规定的一个特性,IE9+,Safari3+,Chrome,Opera10+也帮衬textContent

Polymer

Polymer 是演示构建基于原生Web
Component成效的特级示例。它提供了增选的机制用来创设自定义的Polymer元素,并且提供了重重主导的UI组件,让您可以创制自己的应用程序。

亚洲必赢官网 13

上边你能够见见 my-avatar 元素的大约创制进程,同时我们也获得了想要的标志。

查阅代码演示: 

谷歌(Google)正在努力促进Polymer。请查看 Polymer getting started
guide 查看越来越多示例。

     
首先是拉长和移除事件监听器,由于IE和非IE选取的办法不一样等,IE选取attach伊芙(Eve)nt和detech伊芙nt,非IE采纳add伊芙(Eve)ntListener和remove伊夫(Eve)ntListener,而且IE只支持冒泡(从此时此刻元素冒泡到根元素),而非IE接济冒泡和破获(从根元素捕获到方今元素)。最开首自我是这么做的:

2、outerText

除却效能范围增添到了涵盖调用它的节点之外,outerText与innerText基本相同

X-Tag和Brick

Mozilla开发了和谐的自定义元素
包容库,叫做 X-Tag。X-Tag是一个为启用Web
Component进行多项包容的库,并即将提供对Web Component的完整援助。

以下就是选择X-Tag的 my-avatar 自定义组件,与专业文档非凡看似:

翻看代码演示:

Mozilla同时还创建了一个叫 Brick 的库,其中包涵X-Tag,提供“一组用来便宜飞快构建Web应用程序的UI组件”,使用与谷歌(Google)的Polymer相似的不二法门。

tp.event.on = function(element,event,fn) {
        if (window.attachEvent) {
            //IE
            //第三个参数_realFn是为了修正this
            var realFn = function(e{fn.call(element,e);};
            _realEventCallbackFns[fn] = realFn;
            element.attachEvent("on" + event,realFn);
        } else if (window.addEventListener) {
            element.addEventListener(event, fn,false);
        } else {
            element["on" + event] = fn;
        }
};

第12章,DOM2和DOM3

DOM1级首要定义HTML和XML文档底层结构。DOM2和DOM3则在此基础引入越来越多互动能力,扶助更高级的XML特性。

总结

利用基于组件的架构构建应用程序有过多利(多利(Dolly))益,你能从现有的框架中学到,也能在构建前端Web应用程序时从推荐的Web
Component中读书到。

这场组件化Web王国的旅程,让我们在面临框架和工具的选料时无可如何不决。然则,Web
Component会是最终的点灯!

Web
Component会提供构建应用程序的原生统一的措施
。现有的框架很有可能会转而选用Web
Component或者声明什么与它一头使用。Ember的方针是让迁移到Web
Component越发方便,而脸谱的React则是出现说法整合的好例子,已经有一个 ReactiveElements 演示它了。因为Angular和Polymer都是谷歌的品种,他们很有可能会走到联合。

   
 也就是在一个函数内部去判断是不是是IE,然后相应的推行相应的函数,但是那样,即使加上的风浪监听器很多,每一次都if什么的,我个人感觉很不佳,所以我背后添加了一个增援函数:

DOM2级:

主题:在1级基础上,为节点添加更加多措施和属性

视图:为文档定义了根据样式新闻的不相同视图

事件:表明了什么样运用事件与DOM文档交互

体制:定义了怎么以编程格局来访问和转移CSS样式音信

遍历和限制:引入了遍历DOM文档和甄选其一定部分的新接口

HTML:在1级基础上,添加更加多属性,方法和新接口

外部资源(英文)

  • Eric Bidelman – Google I/O 2014 – Polymer and Web Components change
    everything you know about Web
    development
  • Ryan Seddon – Web Directions – Web Components, The Future of Web
    Development
  • Addy Osmani – LXJS – Componentize The Web: Back To The
    Browser!
  • WebComponents.org a place to discuss and evolve web component
    best-practices
var _listeners = {},
        _addEventListener,
        _removeEventListener;
    if (window.attachEvent) {

        var _realEventCallbackFns = {};
        _addEventListener = function(element,event,fn) {
            //第三个参数_realFn是为了修正this
            var realFn = function(e) {fn.call(element,e);};
            _realEventCallbackFns[fn] = realFn;
            element.attachEvent("on" + event,realFn);
        };
        _removeEventListener = function(element,event,fn) {
            element.detachEvent("on" + event,_realEventCallbackFns[fn]);
        };
    } else if (window.addEventListener) {
        _addEventListener = function(element,event,fn,capture) {
            element.addEventListener(event, fn,capture);
        };
        _removeEventListener = function (element,event,fn,capture) {
            element.removeEventListener(event,fn,capture);
        };
    } else {
        _addEventListener = function(element,event,fn) {
            element["on" + event] = fn;
        };
        _removeEventListener = function(element,event) {
            delete element["on" + event];
        };
    }

检测浏览器是或不是协理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");

         
 那样,整个判定只必要实施五次,前边调用的时候只须求拔取_add伊夫ntListener即可,当然,由于采纳了闭包,tp.event命名空间之外是不足访问这一个函数的。

本着XML命名空间变化

<!-- 不加前缀:-->
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>Example XHTML page</title>
    </head>
    <body>
        Hello World!
    </body>
</html>
<!-- 加前缀:-->
<xhtml:html xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <xhtml:head>
        <xhtml:title>Example XHTML page</xhtml:title>
    </xhtml:head>
    <xhtml:body>
        Hello World!
    </xhtml:body>
</xhtml:html>

错落使用三种语言,命名空间用途才可以反映

DOM2级要旨为半数以上DOM1级方法提供一定于命名空间的版本解决问题

           那这样,tp.event.on就变得万分不难了:

1、Node类型变化

在DOM2级,包蕴下列特定于命名空间的特性

localName:不带命名空间前缀的节点名称

namespaceURI:命名空间URI或(未指定意况下)null

prefix:命名空间前缀或(未指定意况)null

当节点使用了命名空间前缀时,nodeName等于prefix+”:”+localName,如下:

<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>Example XHTML page</title>
    </head>
    <body>
        <s:svg xmlns:s="http://www.w3.org/2000/svg" version="1.1"
            viewBox="0 0 100 100" style="width:100%; height:100%">
            <s:rect x="0" y="0" width="100" height="100" style="fill:red"/>
        </s:svg>
    </body>
</html>

<html>:localName和tagName=”html”,namespaceURI=”

<s:svg>:localName=”svg”,tagName=”s:svg”,namespaceURI=””

tp.event.on = function(element,event,fn) {
        _addEventListener(element,event,fn,false);
         };

DOM3级在此基础再引入:

isDefaultNamespace(namespaceURI),指定的namespaceURI是还是不是是当前节点的默许命名空间

lookupNamespaceURI(prefix),重临给定的prefix的命名空间

lookupPrefix(namespaceURI),重返给定的namespaceURI的前缀

         
而且这么还有一个益处,以前的措施只好利用冒泡格局,但明日,可以拔取捕获,当然,只好非IE才能拔取,这样在背后使用事件代理一些非冒泡的轩然大波的时候越发有用,比如blur和focus事件。

2、Document类型变化

饱含下列与命名空间有关的主意:

createElementNS(namespaceURI,tagName):使用给定的tagName创制一个属于命名空间namespaceURI的新因素

createAttributeNS(namespaceURI,attributeName):使用给定的attributeName创制一个属于命名空间namespaceURI的新特点

getElementsByTagNameNS(namespaceURI,tagName):重临属于命名空间namespaceURI的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","*");

注:只有在文档中设有七个命名空间的时候,那几个与命名空间有关的措施才是须求的

         
 除了事件监听器,还索要事件风云的拉长,删除等,也就是add,fire,remove等,那里就不说了。

3、Element类型变化

重大涉嫌操作特性,新增方法如下

getAttributeNS(namespaceURI,localName):取得属于命名空间namespaceURI且名为localName的特性

getAttributeNodeNS(namespaceURI,localName):取节点

getElementsByTagNameNS(namespaceURI,tagName):再次来到属于命名空间的tagName元素的NodeList

hasAttributeNS(namespaceURI,localName):确定当前元素是不是有一个名为localName的特性,而且该特性的命名空间是namespaceURI。注意:DOM2中央,也平添一个hasAttribute方法,用于不考虑命名空间的事态

removeAttributeNS(namespaceURI,localName):删除特性

setAttributeNS(namespaceURI,qualifiedName,value):设置属于命名空间且名为qualifiedName的特色值为value

setAttributeNodeNS(attNode):设置属于命名空间的性状节点

注:除第二个参数外,那些点子与DOM1级相关办法效果一样

         
在利用事件代理的时候,我们日常要拿走到事件的对象元素,而IE和非IE又是不等同的,所以需求独自写一个函数:

4、NamedNodeMap类型变化

新增方法多数场合只针对特征应用

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

任何变化

         
常用的效率自然仍然阻止事件冒泡以及阻碍默许事件的暴发,很遗憾,IE和非IE处理形式仍然不等同的,比如阻止冒泡IE选取的是cancelBubble,而别的浏览器选拔的是stopPropagation,所以仍旧需求写:

1、DocumentType类型

新增属性:publicId,systemId,internalSubset,前七个象征文档类型声明中的新闻段,在DOM1中不可以访问

使用:document.doctype.publicId

internalSubset用于访问文档类型评释中的额外定义

即使没啥用的说

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;
        }
    };

2、Document类型

转变中绝无仅有与命名空间非亲非故的不二法门:importNode(),用途:从一个文档中拿走一个节点,将其导入到另一个文档

注:每个节点都有一个ownerDocument属性,使用appendChild时传出的节点属于不一致文档,则会出错,importNode则不会

与Element的cloneNode方法极度相似,接收七个参数,要复制的节点,是还是不是复制子节点的布尔值

DOM2级视图添加defaultView属性,指向拥有给定文档的窗口,除IE外,都扶助,IE扶助等价属性:parentWindow

DOM2级要旨为document.implementation对象确定三个新措施:createDocumentType(成立新的DocumentType节点,接收多少个参数:文档类型名称,publicId,systemId),creteDocument(接收多个参数:针对文档元素的namespaceURI,文档元素标签名,新文档的文档类型)

DOM2级HTML为document.implementation新增方法createHTMLDocument,接收一个参数:新创造的文档的标题,唯有Opera和Safari帮忙

       
 事件这一块儿其实我做了N多东西,但是出于讲不完,所以临时不说了。

3、Node类型

唯一一个与命名空间无关变化,isSupported方法用于确定当前节点有所啥能力,接收四个参数:特性名,版本号,存在于hasFeature相同的题目

提议:最好仍旧利用力量检测确定某个特性是还是不是可用

DOM3级:is山姆(Sam)eNode和isEqualNode,接收一个节点参数

is山姆(Sam)eNode是不是同一个目的,指向的是同一个目的

isEqualNode是或不是相同连串,具有杰出属性(相同地方,相同值)

例:

var div1 = document.createElement("div");
div1.setAttribute("class","box");
var div2 = document.createElement("div");
div2.setAttribute("class","box");
alert(div1.isSameNode(div1));   //true
alert(div1.isEqualNode(div2));  //true
alert(div1.isSameNode(div2));   //false

DOM3级:setUserData,接收3个参数:要安装的键,实际数据,处理函数

getUserData传入相同的键可以拿到数据

处理函数接收5个参数:操作类型(1复制,2导入,3刨除,4重命名),数据键,数据值,源节点,目的节点

        注意一下呀,由于JS变量功效域没有block,所以请不要拔取上面那种:

4、框架变化

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++) {

   }
}

样式

概念样式方式:<link/>包括外部文件,<style/>定义嵌入样式,style特性定义针对一定元素样式

//确定浏览器是否支持DOM2级定义CSS能力
var supportsDOM2CSS = document.implementation.hasFeature("CSS","2.0");
var supportsDOM2CSS2 = document.implementation.hasFeature("CSS2","2.0");

style特性中指定的别样CSS属性都将表现为那些style对象的属性,对于利用短划线(background-image)的CSS属性,必须改换为驼峰大小写方式

注:float为js保留字,不能通过轻重写转换,DOM2级样式规定,对应对象属性名应是cssFloat,Firefox,Safari,Opera,Chrome都协助,IE帮助styleFloat

      这样使用变量i已经被重复定义了,所以须要把变量i定义在if以前,即:

1、DOM样式属性和章程:

cssText:访问style特性中的CSS代码

length:CSS属性数量

parentRule:CSS信息的CSSRule对象

getPropertyCssValue(propertyName):重临给定属性值的CSSValue对象

getPropertyPriority(propertyName):若给定的性能使用了!important设置,重返important,否则,重返空串

getPropertyValue(propertyName):再次来到给定属性的字符串值

item(index):重返给定地点的CSS属性名称

removeProperty(propertyName):从体制中去除给定属性

setProperty(propertyName,value,priority):将给定属性设置为相应的值,并加上优先权标志(important或一个空荡荡)

var arr = new Array(),
    i;

操作样式表

CSSStyleSheet类型表示的是样式表,CSSStyleSheet对象是一套只读接口,CSSStyleSheet继承自StyleSheet

运用于文档的富有样式表通过document.styleSheets集合来表示,通过length可以清楚样式表数量,通过方括号法和item方法可以访问每一个样式表

          事件以后,当然就是DOM了,感觉每个库在这些方面都做了不少干活。

1、CSS规则

CSSRule对象表示样式表中每一条规则,实际上是一个供其余多连串型继承的基类型,常见的是CSSStyleRule类型

       
 首先是ready的论断,关于这几个可以看本身其余一篇日记:

2、创设规则

行使insertRule方法,接收五个参数:规则文本,在何地插入规则的目录

支撑浏览器:Firefox,Safari,Opera,Chrome。IE8及更早版本辅助类似措施addRule,接收七个必选参数:选取符文本和CSS样式信息,一个可选参数:插入规则地方

提出:选取从前介绍过的动态加载样式表的技术

       
 那里我根本讲一下tp.dom.query,也就是询问怎么办的,首先看望常用的询问有:#aa,.aa,input。

3、删除规则:慎用

deleteRule接收一个参数:要刨除的平整的岗位

       
 #aa那种比较简单,因为JS提供了API,也就是document.getElementById;input那种也相比好搞,因为JS有document.getElementsByTagName;可是.aa那种方法就相比较纠结了,因为JS没有提供API,幸好,在有些浏览器中依旧提供了API:document.getElementsByClassName,而这个并未提供那一个API的就相比悲剧了,只好遍历所有节点,也就是行使document.getElementsByTagName(*):

遍历

DOM2级遍历和范围定义了逐条遍历DOM结构的品种:NodeIterator,Tree沃克,那三个项目执行深度优先遍历(深搜)

          我此时写了一个协理函数:

NodeIterator类型

能够选拔document.createNodeIterator方法成立实例,接收4个参数:root(源点),whatToShow(要拜访的节点的数字代码),filter(NodeFilter对象,或意味着应当接受或拒绝某种特定节点的函数),entityReferenceExpansion(布尔值,是或不是要推而广之实体引用)

whatToShow是一个掩位码,以常量格局在NodeFilter类型中定义

NodeFilter.SHOW_ALL:显示所有

NodeFilter.SHOW_ELEMENT:显示元素节点

NodeFilter.SHOW_ATTRIBUTE:特性节点,由于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_FRAGMENT:文档片段节点,对HTML没用

NodeFilter.SHOW_NOTATION:符号节点,同上

除NodeFilter.SHOW_ALL外,可以使用按位或操作符组合五个拔取

每个NodeFilter对象唯有一个方法:acceptNode(),再次回到NodeFilter.FILTER_ACCEPT或者NodeFilter.FILTER_SKIP,NodeFilter是一个虚无类型,无法直接开立实例,必要时得以创立一个涵盖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()

var _getElementsByClassName = null;
        if(document.getElementsByClassName) {
                _getElementsByClassName = function(str) {
                    var fetchedEles = document.getElementsByClassName(str),
                        eles = [];

                    for(var i = 0, len = fetchedEles.length; i < len; i++) {
                        eles.push(fetchedEles[i]);
                    }
                    return eles;
                };
        } else {
            _getElementsByClassName = function(str,openClassScan) {
                var eles = [],
                    allElements = document.getElementsByTagName("*"),
                    i;
                if(openClassScan) {
                    for (i = 0; i< allElements.length; i++ ) {
                        if (tp.dom.containClass(allElements[i],str)) {
                            eles.push(allElements[i]);
                        }
                    }
                } else {
                    for (i = 0; i< allElements.length; i++ ) {
                        if (str === allElements[i].className) {
                            eles.push(allElements[i]);
                        }
                    }
                }
                return eles;
            };
        }

TreeWalker

NodeIterator的更尖端版本除了NodeIterator的四个办法外,还提供用于在差异方向遍历DOM的主意:

parentNode():遍历到如今节点父节点

firstChild():到当下节点的首先个头节点

lastChild():到方今节点的末尾一个子节点

nextSibling():到最近节点的下一个同辈节点

previousSibling():到近日节点的上一个同辈节点

行使document.createTree沃克方法,与document.createNodeIterator类似接收4各参数:根节点,要浮现的节点类型,过滤器,是还是不是扩张实体引用布尔值

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

Tree沃·克(Wal·ker)类型还有一个性质:currentNode,通过改动此属性仍可以改变搜索源点

           
我那儿写了一个openClassScan参数,解释一下,这几个参数是为着解决类似于<div
class = “a
b”></div>那种,因为只要要帮助通过API查询如class:a,那么须求各种节点都认清是或不是contain这些class,相比较费时间,而自己认为很多时候不须求,所以默认自己关闭了。

范围(有点难)

DOM2级在Document类型中定义了createRange方法。属于document对象,使用hasFeature或直接检测该措施,可以规定浏览器是或不是帮衬范围

注:新创立的限定间接与成立它的文档关联,只可以用于当前文档

各样范围由一个Range实例表示,下列属性提供了脚下限制在文档中的音信:

startContainer:包蕴限制源点的节点(选区中率先身长节点的父节点)

startOffset:范围在startContainer中源点的偏移量,若startContainer是文件节点,注释节点,CDATA节点,则startOffset就是限量起源从前跳过的字符数量,否则就是限制中首先身材节点的目录

endContainer:蕴涵限制重点的节点(即选区中最后一个节点的父节点)

endOffset:范围在endContainer中终点的偏移量,与startOffset规则一样

commonAncestorContainer:startContainer和endContainer共同祖先节点在文档树地方最深的尤其

           
PS:使用了原生的document.getElementsByClassName的必然不受这么些影响的。

1、使用DOM范围完成简单选取

亚洲必赢官网 ,应用selecNode和selectNodeContents方法应用限制选拔文档一部分,多个主意都吸收一个参数:DOM节点,selectNode采纳任何节点,selectNodeContents选取节点的子节点

例:

<!DOCTYPE html>
<html>
    <body>
        <p id="p1"><b>Hello</b> world!</p>
    </body>
</html>

var range1 = document.createRange();
    range2 = document.createRange();
    p1 = document.getElementById("p1");
range1.selectNode(p1);
range2.selectNodeContainer(p1);

结果

亚洲必赢官网 14

调用selectNode时,startContainer,endContainer,commonAncestorContainer都是流传的父节点,也就是document.body,startOffset等于给定节点在其父节点的childNodes集合中的索引,endOffset=startOffset+1,因为只选了一个节点

调用selectNodeContainer时,startContainer,endContainer,commonAncestorContainer都是流传的节点,也就是<p>元素,startOffset始终等于0,因为范围从给定节点的首个头节点开端,endOffset等于子节点数量,本例中是2

2、使用DOM范围完毕复杂选择(关键)(难度在那边,搞定了那几个,之后的操作就没啥大题目,须求再研商探讨)

3、操作DOM范围中的内容

4、插入DOM范围中的内容

5、折叠DOM范围

6、比较DOM范围

7、复制DOM范围

8、清理DOM范围

           我把每一个询问如:tp.dom.query(“#aa
input”)分为二种,一种为简便询问(也就是如查询:#aaa),其余一种是扑朔迷离查询,每个复杂查询都是由众多简便询问构成的,比如#aaa
input,就可以切成:#aaa和input。

IE8及更早版本中的范围

IE8及更早版本并不协理DOM范围(IE就是如此拽),帮衬类似概念文本范围

           所以,在各样查询的最伊始,必要将传递的查询格式化,比如#aa
>input那种格式化为:#aa >
input,三个空格变为1个空格,>两边必须有一个空格等。

第17章,错误处理与调节

选用try-catch,throw语句得到肯定的错误音信

格式:

try{
     //可能出错的代码
}catch(error){
     //出错时应该怎么处理的代码
}

finally语句是try-catch语句的可选语句,但finally语句一经使用,无论如何都会实施。有了finally语句,catch就成了可选的

注:IE7及更早版本有bug:除非有catch语句,否则不执行finally语句,(又来拽一波了)

         
 之后写一个救助函数,判定是或不是是复杂查询,如若是,那么切开查询字符串,切成数组。

荒唐类型

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

encodeURI,decodeURI,会抛出URIError,少见,那两货的容错性高

相遇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");

           我认为:#aa
input这种实际上固然通过document.getElementById查询将来然后查询它的子孙节点中的所有满足tagName为input的元素;而#aaa
>
input那种就是询问它的子女节点中是否有那种满意条件的因素。现在整整流程比较不难了,对于一个错综复杂查询,首先举行一个简练询问,然后根据查询的结果集合,进行四遍遍历,对各种节点查询它的男女节点或子孙节点,将兼具满足条件的放入到别的一个数组,若是该数组为空,那么直接回到空数组,否则,继续拓展下三次查询(仍然查询孩子节点或子孙节点)。

荒唐事件

其他没有经过try-catch处理的荒唐都会触发window对象的error事件

         
 我觉着,就那样一个成效比较简单的query就够了,不要求落成类似于jquery里面的那样复杂的询问,假使要利用它,其实也很粗略,因为jquery的询问引擎sizzle已经开源,完全可以将它进入到这几个库,近期日toper也是那样做的,要调用sizzle就应用:

大面积错误类型

类型转换错误

数据类型错误

通信错误

tp.use("tp.dom.sizzle",function(sizzle) {});

调节技术

将消息记录到控制台

将错误新闻记录到当前页面

抛出错误

         
感觉JS的兼容性真心很感冒啊,就比如在DOM这一头,为了合营,我都做了很长日子。当然,DOM这一起早晚不止如此一点内容,暂时也不写了。

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

操作终止

不算字符

未找到成员

不解运行时不当

语法错误

系统不可能找到指定资源

          除了DOM,对变量类型的判断和浏览器的检测也是很重大的。

       
 首先,类型判定,由于JS是弱类型语言,而有时候是内需判定它的品种的,当然也得以选拔typeof
去判断,暂时我是那样做的:

  

tp.type = tp.type || {};
tp.type.isArray = function(ele) {
    return "[object Array]" === Object.prototype.toString.call(ele);
};
tp.type.isFunction = function(ele) {
    return "[object Function]" === Object.prototype.toString.call(ele);
};
tp.type.isObject = function(ele) {
    return ("function" === typeof ele) || !!(ele && "object" === typeof ele);
};
tp.type.isString = function(ele) {
    return "[object String]" === Object.prototype.toString.call(ele);
};
tp.type.isNumber = function(ele) {
    return "[object Number]" === Object.prototype.toString.call(ele) && isFinite(ele);
};
tp.type.isBoolean = function(ele) {
    return "boolean" === typeof ele;
};
tp.type.isElement = function(ele) {
    return ele && ele.nodeType == 1;
};
tp.type.isUndefined = function(ele) {
    return "undefined" === typeof ele;
};

       
我看了须臾间,差距的库的判断情势分化,我那时使用的是tangram的论断形式。

        然后就是浏览器判定,我是如此写的:

(function() {
    var ua = navigator.userAgent;
    tp.browser.isIe = ua.hasString("MSIE") && !ua.hasString("Opera");
    tp.browser.isFirefox = ua.hasString("Firefox");
    tp.browser.isChrome = ua.hasString("Chrome");
    tp.browser.isWebKit = ua.hasString("WebKit");
    tp.browser.isGecko = ua.hasString("Gecko") && !ua.hasString("like Gecko");
    tp.browser.isOpera = ua.hasString("Opera");
    tp.browser.isSafari = ua.hasString("Safari") && !ua.hasString('Chrome');
    tp.browser.isStrict = ("CSS1Compat" === document.compatMode);
})();

     
 当然,还有浏览器版本的论断,暂时就不贴出来了。那里基本思路就是判定navigator.useAgent重临的字符串中,每个浏览器里面的那几个字符串是不等同的,当然,那些进程比较恶心,而且有可能前面某一个浏览器会改变它的userAgent,导致整个判定失效,比如IE,听人家说前边新IE要把userAgent搞成firefox,真心搞不懂,那是要逆天啊?

     
 除了那种判断形式,还足以因而判定是还是不是有某一个函数或某一个变量来判定,那种判断形式本身遗忘叫什么名字了,反正从前那种叫浏览器嗅探。

     
 除了代码之外,工具也很要紧,另一篇日记介绍JS工具的:

       
对动画片有趣味的童鞋,可以看看自己的近年攻读JS的顿悟-2,关于动画的。

     
 可以吗,貌似又超时了,先就像是此呢,感觉每一趟写那种日志都会消耗成千上万岁月。

网站地图xml地图