组件化的Web王国,学习笔记11

自定义标签在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");

可组合

事先也研商过,基于组件的架构让组件组合成新组件尤其便于。那样的宏图让组件更加小心,也让此外零件中构建和暴光的作用更好使用。

甭管是给程序添加效果,仍旧用来制作完整的主次,尤其扑朔迷离的效果也能萧规曹随。那就是那种情势的重点利益。

是否有需求把具备的事物转换成组件,事实上取决于你自己。没有任何理由让你的次序由 你自己 的组件组合成你最惊叹的功能 ,乃至 最花哨的功能。而那些零件又扭曲构成任何零件。假设您从那几个方法中取得了好处,就想法地去百折不挠它。然则要注意的是,不要用平等的章程把事情变得复杂,你并不要求过分关怀怎么着让组件重用。而是要关切突显程序的意义。

     
 由于那个库完全是为毕设做的,所以那其中的无独有偶文书都是为促成毕设的某些意义而写的。

症结管理

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交互。那样做的题目就在于,那种做法会让组件相互珍爱。短时间内可能还好,一段时间未来,你在修改程序的时候程序会失控,修改一个组件就会对另一个零部件爆发巨大的震慑。决定移除一个不可以带动预期价值组件可能会让您的应用程序截至工作,因为它背后会有数个零部件看重于它。

此时,解决方案是提供松耦合组件化的Web王国,学习笔记11。的,让组件之间很少或者大致不通晓互相的方案。组件并不直接开立其他零件,在她们需求通讯的时候,他们通过“接口/约定”或者经过 “服务”。我们在构建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和TomDale也很乐于把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 纵然是个新人,然则却一度有诸多的维护者。它由Facebook开发,并且已经完美用于Instagram的UI和一部分Facebook的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中向来不观看,我是看了天猫商城的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树前不会加载任何相关资源。

     
我前边写了一篇日记来兑现英特尔,当然,成效低下,反正大家看看就行了

安顿文本

没有纳入H5规范的习性

Platform.js

唯独,就像是每一遍提到新特色一样,大家不可以确定浏览器是或不是协理那个特点。

美高梅开户网址 11

直到二零一四年一月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伊夫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组件”,使用与谷歌的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特性。

总结

动用基于组件的架构构建应用程序有广大好处,你能从现有的框架中学到,也能在构建前端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萨姆eNode和isEqualNode,接收一个节点参数

is萨姆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沃·克(Wal·ker),那多个种类执行深度优先遍历(深搜)

          我那时写了一个相助函数:

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.createTreeWalker方法,与document.createNodeIterator类似接收4各参数:根节点,要来得的节点类型,过滤器,是还是不是扩充实体引用布尔值

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

Tree沃克类型还有一个性质: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地图