如何克隆一个元素?

3
我已经编写了一个js脚本来克隆元素,但是它只选择第一个元素。下面是代码:
 function clone(sel) {
     var rVxyz = document.querySelector(sel);
     var rVabc = rVxyz.cloneNode(true);
     document.body.appendChild(rVabc) || 
     document.documentElement.appendChild(rVabc);
 };

是的,我知道我已经使用了querySelector,但我无法在querySelectorAll中使用它。我写了类似于这样的代码:

function clone(sel, num) {
    var rVxyz = document.querySelectorAll(sel)[num];
    var rVabc = rVxyz.cloneNode(true);
    document.body.appendChild(rVabc) || 
    document.documentElement.appendChild(rVabc);
};

这只在num等于0时有效,否则无效。 预先感谢。

这仅在num = 0时有效,否则无效。querySelectorAll选择多少个元素?即sel是什么,你的HTML长什么样? - Jaromanda X
querySelectorAll会选择所有具有相同id、class或标签名称的元素。 - MOD ER HACKS
ID的定义是唯一的,不能重复。请提供一个可运行的[mcve]来演示您的问题。 - charlietfl
2个回答

0

但是你的代码是可以运行的……只需要添加几行代码,就能减少错误。

function clone(sel, num) {
  num = parseInt(num);
  var id = !!sel.match('#');
  var elem = (id) ? document.querySelector(sel) : document.querySelectorAll(sel)[num];
  if (elem) {
    var clone = elem.cloneNode(true);
    clone.classList.add('demo'); // just for demo (remove);

    if (id || elem.id) {
      clone.id = elem.id + '-bubuClone';
      console.log( `New clone id="${clone.id}"` );
    }

    document.body.appendChild(clone) || document.documentElement.appendChild(clone);
  } else {
    console.log(
      'Didn\'t found element to clone: ("' + sel + '")' + ( !id ? '[' + num + ']' : '' ) 
    );
  }
}

clone('.test', 2);
clone('.test', 5);
clone('.test', 9);
clone('.test', 15);
clone('#bubu', 15);
clone('#check');
.test, .test-id {
  display: inline-block;
  border: 2px solid orange;
  padding: 5px;
  margin: 5px;
}

.demo {
  border-color: red;
}
<div class="test-id" id="bubu">bubu</div>
<div class="test">0</div>
<div class="test">1</div>
<div class="test" id="test007">2</div>
<div class="test">3</div>
<div class="test">4</div>
<div class="test">5</div>
<div class="test">6</div>
<div class="test">7</div>
<div class="test">8</div>
<div class="test">9</div>
<br>

或者,向函数添加第三个参数,该参数将定义搜索类型(选择器/选择器全部)。

0

这将取决于您作为 sel 参数传递的内容。如果您传递的是一个元素的 id,例如:#someID,那么id必须唯一,因此在 rVxyz 中只能有0个或1个元素。所以除非您包括一些代码来更改 ID,否则不能克隆该元素,即使这样做也不是真正的克隆。

当然,如果您通过传递类选择器,例如 .someClasssel 中,那么有可能有任意数量的元素,从0到n。

我认为更明智的做法是克隆所有匹配的元素,而不是尝试将索引传递给您的函数。因此,clone() 将使用 forEach 来进行操作。

function clone(sel) 
{
    var rVxyz = document.querySelectorAll(sel);
    rVxyz.forEach(function(element) {
         let rVabc = element.cloneNode(true);
         document.body.appendChild(rVabc) || 
         document.documentElement.appendChild(rVabc);
    });
};
 clone("#biz");                 
 clone(".boi");
 clone(".boi:nth-child(2)"); 

测试用的HTML:

<div id="biz"><p>1 Unique thing</p></div>
<div class="boi"><p>2 hi</p></div>
<div class="boi"><p>hello there</p></div>

输出是:
1 独特的东西
2 嗨
3 你好啊
2 嗨
3 你好啊
2 嗨
第一个元素没有被复制,因为ID必须是唯一的。另外,请注意在第二次调用clone()时,我使用了nth-child选择器,因此只克隆了每个父元素中的第二个匹配元素。这样做的好处是,您甚至可以选择每个第二、第三、第四等元素。
只要元素位于同一个父容器元素内,这将起作用。
以下是关于nth-child的更多信息
但是,如果您确实想复制第n个匹配项,例如第2个匹配项,则原始方法也可以工作。您只需要检查是否超出了NodeList rVxyz的结尾即可。
   function clone(sel, num) 
    {
       var rVxyz = document.querySelectorAll(sel);
       var limit = rVxyz.length;
       if (num < limit)
       {
          var rVabc = rVxyz[num].cloneNode(true);
          document.body.appendChild(rVabc) || 
          document.documentElement.appendChild(rVabc);
       }
      else
      {
         console.log(limit);//Do nothing or output error message here.
      }
    };

 clone(".boi", 1);

只克隆第二个匹配元素,只要找到2个或更多元素。


是的,它可以工作,但输出不同。JS 不会停止复制带有 id 的元素... 因此,我们甚至可以复制 <div id="biz"><p>1 Unique thing</p></div>。 - pravin poudel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接