实时和静态DOM元素

Wil*_*een 2 html javascript dom

做一些关于实时或静态DOM收集的研究.我得到的是,当DOM中的更改反映在集合中时,NodeList是一个实时集合.如果不是这种情况,它是一个静态集合.

正在阅读以下问题:

NodeList何时生效,何时是静态的?

答案表明,HTMLCollections总是有效的,NodeList可以是现场的也可以是静态的.

然而,情况仍然如此?我似乎无法重现静态集合.例如document.querySelectorAll,假设(来源:先前给出的链接回答)返回静态集合,但在以下示例中似乎对我有用:

const elements = document.querySelectorAll('.hi');

function change() {
  document.querySelectorAll('.hi')[0].style.backgroundColor = 'red';
}

function checkvalue() {
  console.log(elements[0].style.backgroundColor);
}
Run Code Online (Sandbox Code Playgroud)
<div class="hi">test</div>
<div class="hi">test</div>

<button onclick="change()">change</button>
<button onclick="checkvalue()">checkvalue</button>
Run Code Online (Sandbox Code Playgroud)

在这个例子中,元素NodeList仍然更新红色,因此元素NodeList似乎是活的.

题:

是否仍然存在实时和静态DOM集合,或者现在只存在实时DOM集合?如果静态仍然存在,请举个例子.

T.J*_*der 7

你误会什么活/静:这是集合这是活的还是静态的,而不是元素集合.

如果你这样做:

const spans = document.getElementsByTagName("span");
Run Code Online (Sandbox Code Playgroud)

后来,你添加一个新span的DOM,价值spans.length将增加,因为新跨越添加到收藏; HTMLCollection实例是实时的.

但如果你这样做:

const spans = document.querySelectorAll("span");
Run Code Online (Sandbox Code Playgroud)

后来,你添加一个新span的DOM,价值spans.length不会增加,因为新的跨度不添加到列表中; 在NodeListquerySelectorAll静态的.

这些元素都是生活方式.

例:

const coll = document.getElementsByTagName("span");
const list = document.querySelectorAll("span");
console.log("(before) coll.length = " + coll.length);
console.log("(before) list.length = " + list.length);

console.log("Adding another span");
document.body.appendChild(
  document.createElement("span")
);
console.log("(after)  coll.length = " + coll.length);
console.log("(after)  list.length = " + list.length);
Run Code Online (Sandbox Code Playgroud)
<span></span>
Run Code Online (Sandbox Code Playgroud)

DOM实际上没有静态元素.如果你需要类似的东西,你可以复制元素,使它们不再存在于DOM中,所以你所做的更改(对副本)不会影响DOM中的元素:

const elements = Array.prototype.map.call(
    document.querySelectorAll('.hi'),
    element => element.cloneNode(true)
);
Run Code Online (Sandbox Code Playgroud)

例:

const elements = Array.prototype.map.call(
  document.querySelectorAll('.hi'),
  element => element.cloneNode(true)
);

function change() {
  document.querySelectorAll('.hi')[0].style.backgroundColor = 'red';
}

function checkvalue() {
  console.log(elements[0].style.backgroundColor);
}
Run Code Online (Sandbox Code Playgroud)
<div class="hi">test</div>
<div class="hi">test</div>

<button onclick="change()">change</button>
<button onclick="checkvalue()">checkvalue</button>
Run Code Online (Sandbox Code Playgroud)