2012-08-07 43 views
5

这与问题javascript cloneNode and properties有关。为什么cloneNode排除自定义属性?

我看到相同的行为。 Node.cloneNode不超过我自己添加(代码从原来的职位)的任何属性复制:

var theSource = document.getElementById("someDiv") 
    theSource.dictator = "stalin"; 

    var theClone = theSource.cloneNode(true); 
    alert(theClone.dictator); 

theClone不含任何财产“独裁者”。

我一直无法找到任何解释为什么这种情况。 documentation on MDN指出cloneNode“复制其所有属性及其值”,该行直接从DOM specification本身取得。

这对我来说似乎打破了,因为它使得它几乎不可能做到包含自定义属性的DOM树的深层副本。

我在这里错过了什么吗?

+0

我可能只是避免使用cloneNode,如果我想克隆一些东西,我会实现自己的克隆函数来克隆我认为合适的元素(例如,您可以使用构造函数创建一个新元素,然后复制属性,复制属性和可能的​​其他自定义的东西取决于你的具体情况)。 – trusktr 2016-08-21 06:34:00

回答

7

属性不等于属性。

改为使用setAttribute()和getAttribute()。

var theSource = document.getElementById("someDiv") 
theSource.setAttribute('dictator','stalin'); 

var theClone = theSource.cloneNode(true); 
alert(theClone.getAttribute('dictator')); 
2

经过测试。 cloneNode确实在克隆中包含自定义属性,但该属性不能直接检索。尝试:

var theSource = document.getElementById("someDiv") 
theSource.dictator = "stalin"; 
//or better/more cross browser compatible 
theSource.setAttribute('dictator','stalin'); 

var theClone = theSource.cloneNode(true); 
alert(theClone.getAttribute('dictator')); //so, use getAttribute 

它可能是一个浏览器的问题,克隆expando properties。我从这个相当老的bugzilla report跑了testcase(见后面)。它不适用于Chrome和Firefox(包括最新版本)。

//code from testcase @ bugzilla 
var a = document.createElement("div");  
a.order = 50;  
alert(a.order);  
b = a.cloneNode(true);  
alert(b.order);  
+0

它返回null – 2012-08-07 21:30:41

+0

那么我想它可能是浏览器相关的?在Chrome(最新版本)中可以使用。 – KooiInc 2012-08-07 21:31:50

+0

您必须首先使用'createAttribute'创建属性。 https://developer.mozilla.org/en-US/docs/DOM/document.createAttribute。 – marteljn 2012-08-07 21:40:52

3

不是每个属性都对应一个属性。将自定义属性添加到元素不会添加属性,因此在执行此操作时会发生什么不在DOM规范中。

实际上,当您向主机对象(如DOM节点)添加属性时会发生什么情况完全未指定,并且不能保证可以正常工作,所以我强烈建议不要这样做。相反,如果你想扩展主机对象的功能(就像jQuery和许多其他库一样),我会建议使用包装。

+0

如果你使用包装器,当你想复制这些数据时,你需要制作自己的方法来克隆这些包装器。我认为'cloneNode'应该被弃用,因为只有太多的用例会导致完全失败。 – trusktr 2016-08-21 06:35:28