是否可以将元素附加到 JavaScript 节点列表?

Posted

技术标签:

【中文标题】是否可以将元素附加到 JavaScript 节点列表?【英文标题】:Is it possible to append an element to a JavaScript nodeList? 【发布时间】:2013-12-03 05:21:41 【问题描述】:

我正在动态生成内容,所以我经常以documentFragments 结束,我使用querySelectorAllquerySelector 进行查询,返回一个nodeList 我的documentFragment 中的元素。

有时我想将一个项目添加到列表中,但我在网上找不到任何关于这是否可行的信息。

我试过这样:

 document.querySelectorAll(".translate").item(length+1) = document.createElement("div");

还有这个:

 document.querySelectorAll(".translate").shift(document.createElement("div"));

但两者都不起作用(如预期)

问题: 是否可以手动将元素添加到 NodeList?我猜,不是但还是问。

感谢您提供一些见解?

编辑: 所以更多信息:我正在生成一个动态内容块,我想将其附加到我的页面。默认情况下,该块是英文的。由于用户正在查看中文页面,因此我在动态片段上运行翻译器,然后将其附加到 DOM。在我的页面上,我还有一个元素,比如标题,它应该根据添加的动态内容而改变。我的想法是一步完成 = 尝试向我的nodeList 添加一个元素。但是从现在开始写...我想不可能:-)

【问题讨论】:

你打算以后用这个NodeList做什么? 您是否尝试根据查询创建节点? 查看NodeList.js 【参考方案1】:

与之前描述的元素选择方法不同, querySelectorAll() 返回的 NodeList 不存在:它包含匹配的元素 调用方法时的选择器,但它不会像文档一样更新 变化。 [1]

在这种情况下,NodeList 不存在,因此如果您向其中添加/删除任何内容,那么它不会对文档结构产生任何影响。

NodeList 是一个只读的类数组对象。 [1]

[1]: javascript:权威指南,David Flanagan

【讨论】:

我知道。我有一个documentFragment,我正在QSA 中获取我的nodeList。这个列表我需要翻译(见上面的评论),加上我的元素 X,它不是片段的一部分。问题是如何处理 X? @frequent 来自同一个参考,A NodeList is a read-only array-like object【参考方案2】:

编辑:正如@Sniffer 提到的,NodeLists 是只读的(长度属性和项目)。您可以操作它们的所有其他内容,如下所示,但如果您想操作它们,最好将它们转换为数组。

var list = document.querySelectorAll('div');
var spans = document.querySelectorAll('span');

push(list, spans);
forEach(list, console.log); // all divs and spans on the page

function push(list, items)   
  Array.prototype.push.apply(list, items);
  list.length_ = list.length;
  list.length_ += items.length;


function forEach(list, callback) 
  for (var i=0; i<list.length_; i++) 
    callback(list[i]);
  

将 NodeList 转换为数组可能会更好 (list = Array.prototype.slice(list))。

var list = Array.prototype.slice.call(document.querySelectorAll('div'));
var spans = Array.prototype.slice.call(document.querySelectorAll('span'));

list.push.apply(list, spans);
console.log(list); // array with all divs and spans on page

【讨论】:

有趣。没想到这是可能的。 有用的答案,以及非常有用的技术。在现代 JavaScript 中,您还可以使用更直观的 Array.from(document.querySelectorAll('div'))。您可能会猜到哪个浏览器不支持它,尽管它很容易填充:if(!Array.from) Array.From=function(data) return Array.prototype.slice.call(data); ;【参考方案3】:

为了不涉及数组方法的技术细节,有时创建一个节点名称列表并在列表上循环会更易读。

在本例中,我将相同的事件处理程序分配给两个不同单选按钮组中的所有按钮(其中组中的每个按钮具有相同的名称):

<div>
    <input type="radio" name="acmode" value="1" checked="checked">Phase<br>
    <input type="radio" name="acmode" value="2">Ssr<br>
    <input type="radio" name="acmode" value="3">Relay<br>
</div>
<div>
    <input type="radio" name="powermode" value="0"  checked="checked">Manual<br>
    <input type="radio" name="powermode" value="1">Automatic<br>
</div> 

示例事件处理程序:

var evtRbtnHandler =
    function rbtnHandler() 
        document.getElementById("response11").innerhtml = this.name + ": " + this.value;
    

并分配:

var buttongroup = ["acmode", "powermode"];
buttongroup.forEach(function (name) 
    document.getElementsByName(name).forEach(function (elem) 
        elem.onclick = evtRbtnHandler;
    );
);

在任何情况下,一旦您掌握了每个项目,就可以使用人类可读的代码将其 push() 到一个数组中。

【讨论】:

【参考方案4】:

我还有一个建议。您可以通过查询分隔符(,)选择多个节点,此代码将保存节点变量中保存的所有 h2 和 h3 标签:

var nodes = document.querySelectorAll('h2, h3');

【讨论】:

【参考方案5】:

使用 ES6 Set():

var elems = new Set([
    ...document.querySelectorAll(query1),
    ...document.querySelectorAll(query2)
]);

【讨论】:

以上是关于是否可以将元素附加到 JavaScript 节点列表?的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript 将片段附加到DOM而不是每个节点。

JavaScript HTML DOM 节点

如何使用 Jquery 或 Javascript 定位附加元素,或者如何将该附加元素添加到 DOM?

如何将子节点附加到特定位置

DOM 无法将节点附加到 DOMNodeList (PHP 7.3) 中的元素

javascript 将元素附加到列表