当我可以使用 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
.
来从文档中删除原件
您的第二个示例创建了元素的 副本(其中没有事件处理程序)。
你使用哪种取决于你想要实现什么,以及你想要支持什么浏览器。
下面两个函数做同样的事情 - 首先他们复制一个元素然后清除主体然后添加回元素。我的问题是哪个更好,在什么条件下使用函数的 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
.
您的第二个示例创建了元素的 副本(其中没有事件处理程序)。
你使用哪种取决于你想要实现什么,以及你想要支持什么浏览器。