当我可以使用 querySelector 克隆节点时,为什么要使用 cloneNode?

Why use cloneNode when I can clone a node using querySelector?

下面两个函数做同样的事情 - 首先他们复制一个元素然后清除主体然后添加回元素。我的问题是哪个更好,在什么条件下使用函数的 cloneNode 或另一个不起作用?

使用查询选择器

function noahArc(animal) {
  // Preserve the poor animal and its children
  var arc = document.querySelector(animal);

  // Flood the entire body with rage, water and thunder
  document.body.innerHTML = "";

  // Restore the preserved animal into the post-apocalyptic world
  document.body.appendChild(arc);
}

noahArc('.asd');

使用克隆节点

function noahArc(animal) {
  // Preserve the poor animal and its children
  var arc = document.getElementsByClassName(animal)[0].cloneNode(true);

  // Flood the entire body with rage, water and thunder
  document.body.innerHTML = "";

  // Restore the preserved animal into the post-apocalyptic world
  document.body.appendChild(arc);
}

noahArc('asd');

首先,为免生疑问:querySelector不克隆元素。它只是给你一个已经存在的元素的引用。在没有错误的浏览器中,即使您在获取引用后擦除 body 的内容,该引用仍然有效。这只是意味着该元素不再存在于文档中。

其次,您的编辑和各种评论表明您的代码存在差异,具体取决于您是使用 querySelector 还是 getElementsByClassName 到 select 元素是不正确的。在显示的代码中,它没有任何区别。您的示例中唯一不同的结果是您是否克隆节点。

所以,看看这两个例子:

你的第一个例子在 某些版本的 IE 中会失败,因为它有一个错误,当你分配给 innerHTML 时它会擦除后代元素的内容即使您有对后代元素的引用,它的祖先也是如此。它不应该失败,但它会。 (去年某个时候这个错误花费了我 小时 的调试时间...)我认为 Edge 没有这个错误。我刚刚使用此测试验证它仍然是 IE11 的问题:

function noahArc(animal) {
  var arc = document.querySelector(animal);
  document.body.innerHTML = "";
  document.body.appendChild(arc);
}

noahArc('.asd');
console.log("Done, you should still see 'this is the div' above, but you won't in IE");
<div class="asd">this is the div</div>

除此之外,"better."这取决于你想做什么。

您的第一个示例尝试在文档中保持 相同 元素(可能附加了事件处理程序)。它不会制作副本,并且只能工作(在它工作的浏览器上),因为通过分配给其祖先的 innerHTML.

来从文档中删除原件

您的第二个示例创建了元素的 副本(其中没有事件处理程序)。

你使用哪种取决于你想要实现什么,以及你想要支持什么浏览器。