Html querySelectorAll 不起作用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18735188/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
querySelectorAll not working
提问by Harry
I have a requirement where I have to pickup the last .div
within a container and apply some business logic to it. The selection of the last .div
has to be dynamic because the user has the option to add/remove .div
elements.
我有一个要求,我必须.div
在容器中提取最后一个并对其应用一些业务逻辑。最后的选择.div
必须是动态的,因为用户可以选择添加/删除.div
元素。
Initially I tried with querySelectorAll
but it did not seem to work. So I decided to change it to getElementsByClassName
and surprisingly it worked with the same logic. Can somebody please help me with the reason for why the remove_div
doesn't work while the second one (remove_div_2
) does?
最初我尝试过,querySelectorAll
但似乎没有用。所以我决定将其更改为getElementsByClassName
,令人惊讶的是它以相同的逻辑工作。有人可以帮我解释为什么remove_div
第二个 ( remove_div_2
) 不起作用的原因吗?
Note: I am not looking for a fix/solution to the issue because I have already proceeded with the second option. I just want to know the reason why the option with querySelectorAll
doesn't work.
注意:我不是在寻找该问题的修复/解决方案,因为我已经进行了第二个选项。我只是想知道选项 withquerySelectorAll
不起作用的原因。
Below is my code:
下面是我的代码:
HTML:
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:
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');
};
}
回答by Harry
The reason is because querySelectorAll
method returns a static list. Any changes made to the document after the querySelectorAll
is used (like removeChild
in this case) will not be reflected in the list of nodes returned. Hence elToStyle[elToStyle.length - 1]
would still point to the node that was removed.
原因是因为querySelectorAll
方法返回一个静态列表。querySelectorAll
使用后对文档所做的任何更改(如removeChild
本例中)将不会反映在返回的节点列表中。因此elToStyle[elToStyle.length - 1]
仍将指向已删除的节点。
Whereas, getElementsByClassName
on the other hand returns a live list of nodes. This implies that elToStyle[elToStyle.length - 1]
would always point to the last .div
irrespective of any changes were done to the document after the node list was prepared or not.
而getElementsByClassName
另一方面,返回一个实时节点列表。这意味着无论是否在准备好节点列表之后对文档进行了任何更改,它elToStyle[elToStyle.length - 1]
都将始终指向最后一个.div
。
Below is the extract from the official documentation available here
以下是此处提供的官方文档的摘录
The NodeList object returned by the querySelectorAll() method must be static, not live ([DOM-LEVEL-3-CORE], section 1.1.1). Subsequent changes to the structure of the underlying document must not be reflected in the NodeList object. This means that the object will instead contain a list of matching Element nodes that were in the document at the time the list was created.
querySelectorAll() 方法返回的 NodeList 对象必须是静态的,而不是实时的([DOM-LEVEL-3-CORE],第 1.1.1 节)。对底层文档结构的后续更改不得反映在 NodeList 对象中。这意味着该对象将包含在创建列表时文档中的匹配 Element 节点的列表。
Note:You can see this by doing a console.log(elToStyle);
both before and after the removeChild
.
注意:您可以通过console.log(elToStyle);
在removeChild
.
回答by John
If you want to reference the last division element just do the following...
如果要引用最后一个除法元素,只需执行以下操作...
var id = 'container';
var d = document.getElementById(id).getElementsByTagName('div')
var lastDiv = d[d.length - 1];
..and then apply your querySelector
.
..然后应用你的querySelector
.