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.οnlοad=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.

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值