这个还是很值得记下,一直存在的很大隐患终于解决,由于在 ie<9 中存在内存泄露
,我们经常采用类似 data
的方式来存储数据(其实是将数据关联到节点),但另一方面 ie<9 下又存在 attribute-property 混淆现象
。
那么当我们通过 data 存储数据时,其实节点上只是存放了一个指向存储数据的指针,这个指针作为 expando 存在于节点上,
node.expando=pointer
当调用 cloneNode
时对于其他浏览器都没影响,得到的新节点没有源节点的 expando ,而在 官方 msdn
却有很不起眼的一行 :
If the object being cloned is an element and that element has expandos defined on it, the expandos are copied to the clone when cloneNode is called. Other browsers might handle this differently.
也就说普通属性也会被克隆到新节点,而那个属性其实是个指针,这样就会造成克隆节点与源节点的数据共享。
更危险的是一般事件处理机制也是使用 data 和节点关联的,最终导致的是,克隆节点的事件和源节点的事件完全共享了,一旦删除或修改其中一个节点的事件,另一个节点的事件状态便会陷入不可避免的不一致性。
举例:
<!DOCTYPE html>
<html>
<head>
<title>attr bug for ie<9</title>
</head>
<body>
<div><div>22</div></div>
<script>
window.onload=function(){
var divs=document.getElementsByTagName("div"),
o=divs[0];
var data={my:1};
o.xx=data;
var cloned=o.cloneNode(true);
document.body.appendChild(cloned);
cloned.xx.my=2;
alert(o.xx.my);
};
</script>
</body>
</html>
修复:
不用原生的 cloneNode ,原生的 cloneNode 在 ie 下确实有不少问题:
1. input 个别状态不能 clone
2.flash 不能正确clone
3.原生注册事件也被 clone
4.??
5. expando 也被复制了 (根源则是 attribute-property 的混淆)
修复后的 clone
最主要的事就是:
clone:funciton(node){
var c=clone.cloneNode(true);
c.expando=null; //!!!!
return c;
}
将指针显示去掉,而对于其他用户自己设的 expando 则没办法了,推荐则是完全避免自行设置节点的自定义 attribute, property ,完全采用 data ,并且完全废弃原生的 cloneNode 而调用修复后的 clone.
分享到:
相关推荐
具体来说,使用`attachEvent`绑定的事件处理器在执行`cloneNode`后会被复制到新克隆的节点上,导致事件重复触发。这在开发中会造成意外的副作用,特别是在事件驱动的交互中。 为了解决这个问题,可以采用John Resig...
还要注意的是id属性也会被克隆,也就是克隆后会有两个相同id的元素(如果克隆对象有设置的话),这很容易会导致其他问题,程序会把克隆table的id属性设空。 ps:table请用class来绑定样式,用id的话新table就获取不...
在实际开发中,可以考虑使用文档片段(DocumentFragment)或者节点克隆(cloneNode)等技术来减少对DOM的直接操作。 此外,为了减少跨浏览器兼容性问题,可以考虑使用一些前端框架,如jQuery等,这些框架提供了封装...
- **实践应用**:了解IE下的盒模型兼容性问题,可以确保页面在不同浏览器中的一致性。 **2. CSS 三栏布局的方式,栅格布局实现** - **概念理解**:三栏布局通常指左右固定宽度、中间自适应宽度的布局方式。 - **...
在某些情况下,我们可以通过克隆一个已经存在的模板元素来创建新的DOM元素,以此来替代`createElement`。 **使用模板元素clone** 尽管这种方法比直接创建元素性能提高不多,大约为10%,但在创建和追加少于100个元素...
在JavaScript中,频繁的字符串拼接会导致性能下降,尤其是IE浏览器。使用Array来存储部分字符串,然后join()合并,可以显著提高效率。 优化前: ```javascript var str = ''; for (var i = 0; i ; i++) { str += '...
然而,在某些情况下,直接使用 `innerHTML` 可能会导致性能下降,特别是在 Firefox 和 Safari 这样的浏览器中。为了提高性能,我们可以采用一种名为 `replaceHtml()` 的 DOM 方法。 `replaceHtml()` 函数的主要目的...