繁体   English   中英

querySelectorAll无法正常工作

[英]querySelectorAll not working

我有一个要求,我必须在容器中拾取最后一个.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');
       };
   }

原因是querySelectorAll方法返回一个静态列表。 使用querySelectorAll后对文档所做的任何更改(如本例中的removeChild )都不会反映在返回的节点列表中。 因此, elToStyle[elToStyle.length - 1]仍将指向已删除的节点。

而另一方面, getElementsByClassName返回一个实时的节点列表。 这意味着elToStyle[elToStyle.length - 1]将始终指向最后一个.div而不管在准备好节点列表之后是​​否对文档进行了任何更改。

以下是此处提供的官方文档摘录

querySelectorAll()方法返回的NodeList对象必须是静态的,而不是实时的([DOM-LEVEL-3-CORE],第1.1.1节)。 对底层文档结构的后续更改不得反映在NodeList对象中。 这意味着该对象将包含一个匹配的Element节点列表,这些节点在创建列表时位于文档中。

注意:你可以通过执行console.log(elToStyle);来看到这个console.log(elToStyle); removeChild之前和之后。

如果你想引用最后一个除法元素,只需执行以下操作即可...

var id = 'container';
var d = document.getElementById(id).getElementsByTagName('div')
var lastDiv = d[d.length - 1];

..然后应用您的querySelector

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM