带有后代的queryselectorAll未正确选择 [英] queryselectorAll with descendant not selecting correctly

查看:34
本文介绍了带有后代的queryselectorAll未正确选择的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我具有以下DOM结构:

I have the following DOM structure:

    var parent = document.querySelector(".test");
    var navChild = parent.querySelectorAll("ul > li > a");
    for (i = 0; i < navChild.length; i++) {
            navChild[i].style.backgroundColor = "red";
        }
    console.log(navChild.lenght);
    console.log(navChild);

<!-- begin snippet: js hide: false console: true babel: false -->
    <ul>
      <li class="test">
        <a>ssss</a> <!--this will also be affected -->
        <ul>
          <li><a>fsfsf</a></li>
          <li><a>sff</a></li>
          <li><a>ggg</a></li>
        </ul>
      </li>
    </ul>

我想使用香草javascript并从 li 开始使用类test选择3个 a 标记.我将其放入 parent 变量中,然后使用querySelectorAll尝试仅获取下一个列表中的 a 标记.但是,返回的节点列表也包括第一个 a 标记,即使它不是后代.这是我的代码:

I want to select the 3 a tags using vanilla javascript and starting from the li with the class test. I put this in a parent variable and then use querySelectorAll to try to get only the a tags that are inside the next list. However, the nodelist that is returned also includes the very first a tag even though it's not a descendant. This is my code:

var navChild = parent.querySelectorAll("ul > li > a");

真正奇怪的是,如果我仅查询 li 后代,我只会得到3.所以我不明白为什么当我查询那个 li 的子代后我还获得了第一个 a 标记,该标记在DOM上位于两个级别.

What's really weird is that if I query for just the li descendants I get only the 3. So I don't understand why when I query for the child descendant of that li I also get that first a tag that is two levels up on the DOM.

我知道我可以使用jQuery来做到这一点,但我不想使用它.

I know I could do this using jQuery but I don't want to use it.

已编辑以显示如何设置父变量

我尝试在第一个 a a 标记添加到 childs 变量中>我不想包含在childs节点列表中的标签.

I'm trying to add those a tags to the childs variable after I've hit the enter keyboard button while on the first a tag that I don't want to include in the childs node list.

var alinks = document.querySelectorAll('.test > a');
[].forEach.call(alinks, function(link){
    link.addEventListener('keyup', function(e){
        e.preventDefault();
        if(e.keyCode === 13) {
            var linkParent = e.target.parentElement;
            var childs = menuParent.querySelectorAll('ul > li > a');
        }        
    })
});

当我登录 linkParent 时,它已被正确设置为 li 类别为 test 的目录.我不明白为什么然后从那里运行查询仍然会包含第一个 a 标记.如前所述,如果我只查询 ul>li ,它为我提供了正确的 li 标记.

When I log linkParent it is correctly being set as the li with class test. I don't understand why then if I run the query from there it still includes the very first a tag. As I previously stated, if I query just ul > li it gives me the correct li tags.

推荐答案

这是因为您要忽略的第一个< a> 标记仍属于选择器规则 ul>&一个.因此,即使您以< li class ="test"> 作为根来开始查询(顺便说一句也可以,但是我不知道为什么其他答案会说document仍然是根目录),它找到的第一个子元素是< a> 标记,并且实际上,它是&li; li 的子元素.< ul> 的子级.结束这一事实的事实超过"了您指定的根.

This is because the first <a> tag you're trying to ignore still falls into the selector rule ul > li > a. So, even though you start the query with the <li class="test"> as the root (which does work by the way, I don't know why the other answers say that the document is still the root), the first child element it finds is the <a> tag and, indeed, it is the child of an <li> which is the child of a <ul>. The fact that this winds up going "above" your specified root is ignored.

修改:如果您希望选择器规则也作用于根目录,则可以改用它:

If you want the selector rule to be scoped to the root as well, you can use this instead:

parent.querySelectorAll(":scope ul > li > a");

为进一步说明,浏览器CSS引擎进行评估CSS规则从右到左.在您看来,您希望浏览器从根目录(父< li class ="test"> )启动,然后找到一个< ul> 标记然后找到< li> 标签,然后找到< a> 标签.

And to further clarify, browser CSS engines evaluate CSS rules right-to-left. In your mind, you want the browser to start at the root (the parent <li class="test">) and then find a <ul> tag and then find a <li> tag and then find an <a> tag.

但是,浏览器从根目录开始,然后在根目录下查找所有< a> 标记.然后,它检查< a> 标记是否在< li> 内,然后检查< li> code>< ul> .因此< li class ="parent"> 标记确实是根,但此后它不遵循选择器规则的从左到右的层次结构,因此从右到右左.

However, the browser starts with the root, but then looks for all of the <a> tags below the root. Then it checks if the <a> tag is within an <li> and then if the <li> is within a <ul>. So the <li class="parent"> tag really is the root, but it does not follow the left-to-right hierarchy of your selector rule after that, it goes right-to-left.

这篇关于带有后代的queryselectorAll未正确选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆