您的位置:首页 > Web前端 > JavaScript

html5shiv.js分析-读源码之javascript系列

2013-11-15 14:34 363 查看

xiaolingzi 发表于 2012-05-31 23:42:29

首先,我们先了解一下html5shiv.js是什么。

html5shiv.js是一套实现让ie低版本等浏览器支持html5标签的解决方案。

实现原理:见如何让ie低版本浏览器支持html5标签

废话不多说,我们先上源代码,代码有点长,但保持原来的注释有利于大家理解,不想直接阅读的就点收缩代码然后往下看。源码原地址:https://github.com/aFarkas/html5shiv

-收缩代码
代码结构分析:

1.整个代码放在一个匿名函数里面并执行,该匿名使用的模式如下:

(function{}())

受到作用域的限制,执行时将当前window(this)和document作为参数传递进去。关于匿名函数执行形式的相关说明请参考之前的文章javascript匿名函数的各种执行形式

2.我们从上往下依次浏览一下代码,并将代码划分为五部分。

第一部分是从开始到第30行。

第二部分是从第31行到55行。

第三部分是从56行到234行。

第四部分是从235行到278行。

第五部分是剩下部分。

好,那么下面我们就从这五部分中分别找出我们可以学习的一些知识点。

第一部分:该部分主要是私有变量的定义,学习到的知识点有:

1.了解到不是所有元素都可以在IE中进行复制,具体参看saveClones 的定义和上面的注释。

2.了解到可以通过一对空大括号{}对一对象进行初始化,见expandoData的定义。

3.了解到变量在开始集中定义的习惯。因为在javascript中,就算将变量定义在其他地方也会预先执行定义,所以可以集中在前面一起定义,这样也有利于变量的管理。

第二部分:执行一个匿名函数来检测浏览器对html5中的css和未知标签的支持情况,并保存结果。学到的知识点有:

1.如何检测浏览器对html5的样式的支持。此处的思路是通过定义一个超链接元素a,然后检测在当前浏览器中a元素是否具备hidden属性,hidden为html5中新增的一个属性,使用该属性可以对元素进行隐藏。

判断的代码如下:


supportsHtml5Styles = (
'hidden'
in
a);


对各浏览器的测试结果如下:


浏览器支持情况
Chrome(18.0.1025.168 m)true
FireFox(12.0)true
Safari(5.1.7)true
Opera(11.64)true
IE9false
IE8false
IE7false
2.如何检测浏览器对未知元素的支持情况。此处的思路是,给定义的a元素填充一未知元素,然后检测a的子元素的个数,若等于1则表示支持未知元素,否则不支持。其次通过检查一个错位执行的支持情况(document.createElement)('a');,但个人测试各浏览器都通过,不知道作者检查是哪些浏览器。最后才通过对文档碎片节点的一些方法的支持情况来进行判断。

对各浏览器的测试结果如下:
a.childNodes.
length

(document.createElement)('a')frag.cloneNodefrag.createDocumentFragmentfrag.
createElement

Chrome(18.0.1025.168 m)1通过definedundefinedundefined
FireFox(12.0)1通过definedundefinedundefined
Safari(5.1.7)1通过definedundefinedundefined
Opera(11.64)1通过definedundefinedundefined
IE91通过definedundefinedundefined
IE80通过defineddefineddefined
IE70通过defineddefineddefined
第三部分:该部分主要是定义一系列的私有方法。学到的知识点有如下:

1.了解了个浏览器对lastChild的支持情况。我们来看addStyleSheet方法,该方法的主要作用是将样式添加到页面中。我们留意到在加入style标签的时候前面多加了一个x。为什么要这样子做呢?这是由于在只有一个节点的情况lastChild会出现兼容性问题,主要表现在IE8和IE7无法通过它来获取到那唯一的节点。

对各浏览器的测试结果如下:
p.lastChild(不加x)p.lastChild(加x)
Chrome(18.0.1025.168 m)object HTMLStyleElementobject HTMLStyleElement
FireFox(12.0)object HTMLStyleElementobject HTMLStyleElement
Safari(5.1.7)object HTMLStyleElementobject HTMLStyleElement
Opera(11.64)object HTMLStyleElementobject HTMLStyleElement
IE9object HTMLStyleElementobject HTMLStyleElement
IE8nullobject HTMLStyleElement
IE7nullobject
2.Function的使用,注意这里是首字母大写的。此处的使用请查看shivMethods方法。Function主要是用来实现动态执行。它可以实现跟eval一样的工作,但由于它在性能方面胜过eval,所以很多人都推荐使用Function。

Function的执行形式如下:
var 函数名 = new Function('argument1','argument2',...,'argumentN','函数体');
或者
var 函数名 = new Function('argument1,argument2,...,argumentN','函数体');
或者
new Function('执行体');

我们看到上面的形式都使用了new关键字进行实例化,但是我们看到本例源码中却没有new,经过测试发现new关键字可以省略。

3.createDocumentFragment即创建文档碎片节点的使用。创建文档碎片节点的目的是为了减少浏览器渲染的次数来提升性能。比如,当我们要往页面中添加一系列节点时,如果每次都实时向页面使用appendChild来添加节点时,那么每次浏览器都会渲染一次,而过多次数的渲染就会造成性能问题。如果我们先把要添加的节点都先加到文档碎片节点中去,完成后再一次添加到页面中去就只渲染一次。

第四部分:该部分主要定义html5对象的一些属性和方法。学到的知识点如下:

1.通过json的方式进行属性和方法的封装。可以大大减少全局变量的污染。具体没必要再详说。

2.通过将私有方法或属性赋值给全局对象的属性来将方法公开。比如当我们定义了许多方法或属性,但我们不想公开所有方法或属性,此时就可以通过闭包将方法私有化,然后再通过返回赋值给全局变量的方式公开部分属性和方法。如此处通过名字叫html5的全局对象的属性进行公开。

第五部分:该部分主要是将html5对象保留给全局window,并执行入口函数。学到的知识点主要是如何在函数中将对象暴露给window(全局化)。

除了上面说的知识点外,还有一个非常重要的地方就是学习别人优秀的设计模式和架构。

好吧,文章就到此结束。如有不对之处欢迎指出交流。

转载请注明出处:http://xxling.com/article/41.aspx
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: