我有一个要求,我必须在容器中拾取最后.div
并对其应用一些业务逻辑。最后.div
的选择必须是动态的,因为用户可以选择添加/删除.div
元素。
最初我尝试使用querySelectorAll
,但似乎没有用。因此我决定将其更改为getElementsByClassName
,令人惊讶的是它使用相同的逻辑。有人可以帮助我解释为什么remove_div
不起作用而第二个(remove_div_2
)不起作用的原因?
注意:我不是在寻找问题的修复/解决方案,因为我已经开始使用第二个选项了。我只是想知道querySelectorAll
选项不起作用的原因。
以下是我的代码:
HTML:
<div id='container'>
<div id='div1' class='div'>This is Div 1</div>
<div id='div2' class='div'>This is Div 2</div>
<div id='div3' class='div'>This is Div 3</div>
</div>
<button type='button' id='append_div'>Append Div</button>
<button type='button' id='remove_div'>Remove Div</button>
<button type='button' id='remove_div_2'>Remove Div 2</button>
JavaScript的:
window.onload = function () {
var elementToStyle = document.querySelectorAll("#container .div");
elementToStyle[elementToStyle.length - 1].classList.add('red');
document.getElementById('append_div').onclick = function () {
var divToInsert = document.createElement('div');
divToInsert.id = 'new_div';
divToInsert.className = 'div';
divToInsert.innerHTML = 'This is an appended div';
document.getElementById('container').appendChild(divToInsert);
var elToStyle = document.querySelectorAll("#container .div");
for (i = 0; i < elToStyle.length; i++)
elToStyle[i].classList.remove('red');
elToStyle[elToStyle.length - 1].classList.add('red');
};
document.getElementById('remove_div').onclick = function () {
var elToStyle = document.querySelectorAll("#container .div");
document.getElementById('container').removeChild(elToStyle[elToStyle.length - 1]);
elToStyle[elToStyle.length - 1].classList.add('red');
};
document.getElementById('remove_div_2').onclick = function () {
var elToStyle = document.getElementsByClassName('div');
document.getElementById('container').removeChild(elToStyle[elToStyle.length - 1]);
elToStyle[elToStyle.length - 1].classList.add('red');
};
}
答案 0 :(得分:9)
原因是因为querySelectorAll
方法返回静态列表。在使用querySelectorAll
之后对文档所做的任何更改(在本例中为removeChild
)都不会反映在返回的节点列表中。因此elToStyle[elToStyle.length - 1]
仍将指向已删除的节点。
而另一方面,getElementsByClassName
返回一个实时的节点列表。这意味着elToStyle[elToStyle.length - 1]
始终指向最后.div
,无论在准备好节点列表之后是否对文档进行了任何更改。
以下是可用的官方文档here
的摘录querySelectorAll()方法返回的NodeList对象必须是 静态的,不是活的([DOM-LEVEL-3-CORE],第1.1.1节)。随后 不得对基础文档的结构进行更改 反映在NodeList对象中。这意味着对象会 而是包含一个匹配的元素节点列表 创建列表时的文档。
注意:您可以在console.log(elToStyle);
之前和之后执行removeChild
来查看此内容。
答案 1 :(得分:0)
如果你想引用最后一个分割元素,只需执行以下操作......
var id = 'container';
var d = document.getElementById(id).getElementsByTagName('div')
var lastDiv = d[d.length - 1];
..然后应用querySelector
。