`
yiminghe
  • 浏览: 1466344 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

ie 下 cloneNode 导致的属性克隆

 
阅读更多

这个还是很值得记下,一直存在的很大隐患终于解决,由于在 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.

 

分享到:
评论
1 楼 luolonghao 2011-08-24  
发现KISSY的文档越来越完善

相关推荐

    javascript dom操作之cloneNode文本节点克隆使用技巧

    具体来说,使用`attachEvent`绑定的事件处理器在执行`cloneNode`后会被复制到新克隆的节点上,导致事件重复触发。这在开发中会造成意外的副作用,特别是在事件驱动的交互中。 为了解决这个问题,可以采用John Resig...

    JavaScript 用cloneNode方法克隆节点的代码

    创建一个节点通常需要使用如createElement、setAttribute、appendChild等方法,而cloneNode提供了一种更加高效的克隆方式。 cloneNode方法有两种用法,分别是浅拷贝和深拷贝。当我们调用cloneNode方法时,需要传递...

    IE下使用cloneNode注意事项分享

    总结来说,在使用`cloneNode`时,特别是在IE环境下,务必谨慎处理`script`、`iframe`和`link`等可能执行脚本的节点,确保克隆操作不会导致意外的代码执行或副作用。最佳实践是尽可能减少不必要的子节点,或者在克隆...

    javascript 拷贝节点cloneNode()使用介绍.docx

    在JavaScript中,`cloneNode()`方法是DOM(Document Object Model)操作中的一个重要功能,主要用于复制(克隆)DOM树中的节点及其属性。这对于创建复杂的用户界面或者动态调整页面内容时非常有用。 #### 一、...

    htmljs克隆标签

    这可能导致不必要的性能消耗或逻辑错误,因此在实际使用中,可能需要根据具体情况清除或重新绑定克隆后的元素上的事件。 总之,"htmljs克隆标签"是一个重要的前端开发技巧,它提供了动态更新页面内容的能力,让网页...

    javascript cloneNode()方法的使用

    javascript 中的 cloneNode() 方法是用来克隆一个元素的,包括其所有子元素和属性。该方法返回克隆的元素,并且可以选择是否克隆元素的所有子元素。 在上面的实例代码中,我们使用了 cloneNode() 方法来克隆一个 ...

    教你javascript克隆dom结点,浅复制结点,深复制结点

    DOM节点克隆是通过调用`cloneNode()`方法实现的。这个方法接受一个布尔参数,如果为`true`,则执行深复制;如果为`false`或不传参,则执行浅复制。 1. 浅复制(Shallow Copy) 浅复制仅复制节点本身及其属性,但不...

    DOM节点深度克隆函数cloneNode()用法实例

    在JavaScript中,DOM(Document...然而,需要注意的是,深度克隆也会复制节点上的所有属性和事件监听器,可能会导致性能问题,特别是在处理大量或复杂的DOM结构时。因此,在使用时应根据具体需求权衡是否需要深度克隆。

    Opera下cloneNode的bug

    总结来说,尽管`cloneNode`在多数情况下是可靠的,但在特定环境下,如Opera中克隆Form节点时,可能需要采用更稳妥的方法。开发者应关注浏览器的特性和行为差异,以便在遇到兼容性问题时能迅速找到解决方案,确保代码...

    js解析XML常用对象、属性、方法

    - `textContent`: 返回属性的文本表示形式(IE 特性)。 - `xml`: 返回属性的 XML 表达形式(IE 特性)。 以上介绍了 JavaScript 在解析 XML 时所涉及的一些关键对象、属性和方法。这些知识对于理解如何使用 ...

    JAVASCRIPT操作DOM建立增加删除克隆访问节点示例宣贯.pdf

    JavaScript 操作 DOM 建立增加删除克隆访问节点示例宣贯 在 JavaScript 中,DOM(Document Object Model)是指文档对象模型,它是 HTML 和 XML 文档的编程接口。通过 DOM,我们可以动态地操作文档的结构、样式和...

    javascript 拷贝节点cloneNode()使用介绍

    - 克隆的节点不会克隆事件处理器(event handlers),因为事件监听器通常不是节点的属性或方法。 - 如果节点是通过脚本动态生成的(例如使用document.createElement),而不是在HTML中直接定义,那么在使用克隆节点...

    jQuery-1.9.1源码分析系列(十一)DOM操作续之克隆节点

    2. **修正IE浏览器下的克隆问题**:对于IE浏览器,由于其存在一些兼容性问题,可能无法正确克隆节点。jQuery提供了一个`fixCloneNodeIssues`函数来解决IE中的克隆问题。 3. **克隆缓存数据(包括绑定的事件)**:...

    HTML DOM 常用的属性和方法

    - `cloneNode(deep)`:复制当前节点,可选择是否连同子节点一起复制。 - `hasChildNodes()`:检查当前节点是否有子节点。 - `insertBefore(newNode, refNode)`:在指定子节点之前插入新的节点。 - `removeChild(node...

    javascript节点属性和方法

    10. nextSibling:返回当前节点的下一个兄弟节点(只读) 11. nodeName:返回节点的名字(只读) 12. nodeType:返回节点的类型(只读) 13. nodeTypedValue:存储节点值(可读写) 14. nodeValue:返回节点的文本...

Global site tag (gtag.js) - Google Analytics