DOM的小事情
本来想要介绍Kissy的Seed模块的,这是KISSY最核心的一个部分,我对它的理解并不够深入。暂且先放下,免得误人误己。本文主要是要讲KISSY.DOM模块的事情,我只讲KISSY的DOM模块里面用到的JS知识点,而不是去介绍KISSY的API,所以就算对KISSY木有兴趣,也是可以看的。
对DOM的操作部分,我想就没必要讲了,就算是个没入行的前端,(我也没入行),也知道createElement('div')是创建一个div了。所以这部份就不介绍了。
我首先想介绍的是是三个概念:property、attribute、data(自定义属性)
1.Property和Attribute
看一下代码:
<input id = "ex_text" type = "text" value = "123"/>
这行代码没什么特别,当(非IE)浏览器加载后,文本框里面显示的就是123,那么value这个property或者attribute都是123.但是我们在浏览器上修改了文本框里面的值,这时property和attribute就不一样了。假如我们把123改成了456,那么value的property是456,但是attribute还是123.结论就是,attribute相对文档来说是静态的,property是动态的。前者表示从文档中获取的状态信息,后者则表示文档的动态状态信息。
为什么会有这个区别呢,因为Attribute本来指的就是HTML文本标签属性,Property指的是DOM对象的属性。我们明白浏览器是以DOM为标准显示的,所以Property是动态的,Attribute是静态的。同时我们还要注意一个问题,在IE6、7、8,Property和Attribute是不区分的,这时一个bug(反正就是不符合W3C标准),可喜的是IE9已经修复了。
下一步讨论的是,怎么分别获取和设置元素的property和attribute呢?
如果你已经理清Property和Attribute的概念,这个就很容易了。我们在js中操作的都是DOM元素,elem[value]就是DOM对应的property;对于Attribute,我们可以用Element提供的接口setAttribute/getAttribute来操作。
如果你习惯于用getAttribute来获取一个文本框的实时值,你肯定是个IE-only的程序猿。
下一个问题:自定义属性。
2.Custom Property
假如我们为DOM元素elem设置一个自定义属性data,data指向一个function,我们通常的做法:elem['data'] = function() {};
这里有个循环引用,elem引用了function,function的作用域保存了elem的引用。
在除IE以外的其他浏览器,这是没有问题的,但在IE下有可能会掉。我们知道,当有两个对象互相引用了,没有第三个对象对这两个对象引用的话,它们会垃圾回收机制回收掉的。(PS:提起互相引用,我们想起闭包,闭包是两个对象互相引用后,其中某个元素被外部元素引用,所以才不会回收。)但是在IE下,当一个DOM元素和JS对象互相引用的时候,IE的垃圾回收不会释放这两个对象。当这样的东西多了之后,内存就不够用了。
为了避开这样的bug,我们只好在函数执行完,手动设置elem['data']=null,来砍掉一个引用。
还有一个办法,就是我要讲的KISSY里面的data方法。
KISSY会在开辟一个空间来专门处理自定义属性,这个空间叫dataCache。KISSY为每个设置自定义属性的元素生成一个唯一的EXPANDO,直接加在元素的property上。elem[EXPANDO] = S.guid();每个EXPANDO是dataCache上有一个索引。凭借这个EXPANDO可以在dataCache上找到属于这个元素的cache空间。cache = dataCache[key]。然后我们在这个cache空间上添加elem的属性。cache['data'] = function(){};
这样每个元素都没有直接和function有引用,而elem的EXPANDO相当于一个凭证,凭借这个独特的KEY去dataCache上找到自己的方法。
KISSY把上述的步骤封装成data方法,Ks-elem.data('name',value);
另外,IE的这个独特的bug,还隐藏这很多问题。下次讨论Event的时候还会发现KISSY因为它做出的调整。
3.DOM的样式操作
我们下次再讲,哈哈。
我算是保住三分之一了,你懂的!
参考:
http://w3help.org/zh-cn/causes/SD9006
——[SD9006: IE 混淆了 DOM 对象属性(property)及 HTML 标签属性(attribute),造成了对 setAttribute、getAttribute 的不正确实现]