如何使用自定义属性克隆HTML节点?

时间:2017-01-02 15:01:13

标签: javascript html dom

我正在编辑并希望使用JavaScript克隆带有自定义属性的HTML节点。 我只找到了a way using setAttribute(),但它将我的自定义属性转换为字符串:

// Using custom attributes
var html = document.createElement("div");
var obj  = {test: 123,html: html};
html.obj = obj;
var cloned = html.cloneNode(true);
console.log(cloned.obj); // returns null

// Using setAttribute
var html = document.createElement("div");
var obj  = {test: 123, html: html};
html.setAttribute("obj") = obj;
var cloned = html.cloneNode(true);
console.log(cloned.getAttribute("obj")); // returns "[object Object]"

如何使用对象克隆html元素?

3 个答案:

答案 0 :(得分:0)

HTML中的属性是字符串值,而不是JavaScript对象和JavaScript属性。 cloneNode操作仅克隆HTML内在函数而不是顶部添加的任何内容,它与深层对象副本不同。

您需要手动执行此操作:

function cloneCustomNode(node) {

    var clone  node.cloneNode(); // the deep=true parameter is not fully supported, so I'm not using it
    clone.obj = node.obj; // this will copy the reference to the object, it will not perform a deep-copy clone of the 'obj' object
    return clone;
}

这可以推广用于将任何自定义JavaScript属性从一个对象复制到另一个对象,不包括那些已在默认值(defaultNode)中定义的属性。

var defaultNode = document.createElement("div");

function cloneNodeWithAdditionalProperties(node) {

    var clone  node.cloneNode();

    for(var propertyName in node) {

        if( !( propertyName in genericNode ) ) {

            clone[ propertyName ] = node[ propertyName ];
        }
    }

    return clone;
}

cloneNodeWithAdditionalProperties将在O( n )时间内运行,因为if( x in y )操作是哈希表查找,其复杂度为O( 1 )(其中n是属性数)。

答案 1 :(得分:0)

您可以使用HTMLElement.dataset的属性,但是api只允许存储字符串,这意味着在设置时使用JSON.stringify()并且在获取数组或对象时使用JSON.parse()



var html = document.createElement("div");
var obj  = {test: 123,html: html};
html.dataset.obj = JSON.stringify(obj);
var cloned = html.cloneNode(true);
console.log(JSON.parse(cloned.dataset.obj)); 




答案 2 :(得分:0)

一种方法是使用Object.keys()迭代节点(这是一个Object)并将发现的属性及其属性值应用于创建的节点,例如:

// named function to follow DRY principles;
// n: DOM node, the node to be cloned:
function customClone(n) {

  // creating a temporary element to hold the
  // cloned node:
  let temp = n.cloneNode(true);

  // Using Object.keys() to obtain an Array of
  // properties of the Object which are not
  // inherited from its prototype, and then
  // using Array.prototype.forEach() to iterate
  // over that array of properties:
  Object.keys(n).forEach(

    // using an Arrow function, here 'property' is
    // the current property of the Array of properties
    // over which we're iterating, and then we
    // explicitly assign the property-value of the
    // node that was cloned to the property-value of
    // that same property on the clone:
    property => temp[property] = n[property]
  );

  // returning the clone to the calling context:
  return temp;
}

let html = document.createElement("div"),
  obj = {
    test: 123,
    html: html
  };
html.obj = obj;

let cloned = customClone(html);
console.log(cloned.obj);

function customClone(n) {
  let temp = n.cloneNode(true);
  Object.keys(n).forEach(
    property => temp[property] = n[property]
  );
  return temp;
}

let html = document.createElement("div"),
  obj = {
    test: 123,
    html: html
  };
html.obj = obj;

let cloned = customClone(html);
console.log(cloned.obj);

JS Fiddle demo

参考文献:

相关问题