【问题标题】:why a nested element is selected by last-of-type?为什么最后一个类型选择嵌套元素?
【发布时间】:2017-12-19 16:23:01
【问题描述】:

我有一个非常简单的 HTML 结构,如下所示:

<div>
    <div>a<div>a1</div></div>
    <div>b</div>
    <p>c</p>
    <div>d</div>
</div>

document.body.querySelector('div &gt; div:last-of-type') 返回&lt;div&gt;a1&lt;/div&gt;,而不是&lt;div&gt;d&lt;/div&gt;

我认为document.body.querySelector('div &gt; div:last-of-type') 应该与document.body.querySelector('div &gt; div:nth-of-type(3)') 相同,后者返回&lt;div&gt;d&lt;/div&gt;

总结一下我的问题:

  1. 为什么document.body.querySelector('div &gt; div:last-of-type') 返回&lt;div&gt;a1&lt;/div&gt;,而不是&lt;div&gt;d&lt;/div&gt;?是bug吗?

  2. 选择&lt;div&gt;d&lt;/div&gt;的正确方法是什么?

【问题讨论】:

    标签: javascript html dom css-selectors


    【解决方案1】:
    1. 为什么document.body.querySelector('div &gt; div:last-of-type') 返回&lt;div&gt;a1&lt;/div&gt;,而不是&lt;div&gt;d&lt;/div&gt;?是bug吗?

      不,这不是错误。原因有两个:

      1. 如果选择器匹配多个元素,querySelector() 仅返回第一个匹配元素。
      2. 选择器的范围不限于调用querySelector() 方法的元素。


      由于&lt;div&gt;a1&lt;/div&gt; 是第一个与div &gt; div:last-of-type 匹配的元素,这就是您的代码返回的内容。

    2. 选择&lt;div&gt;d&lt;/div&gt;的正确方法是什么?

      document.querySelector('body > div > div:last-of-type')
      

      不必把事情复杂化。

    【讨论】:

      【解决方案2】:

      所以这是获取最后一个孩子的规范方法

      console.log(document.body.querySelector('div').lastElementChild)
      <div>
          <div>a<div>a1</div></div>
          <div>b</div>
          <p>c</p>
          <div>d</div>
      </div>

      【讨论】:

        【解决方案3】:

        根据document#querySelectorspec

        Document、DocumentFragment 和 DocumentFragment 上的 querySelector() 方法 元素接口必须返回第一个匹配的元素节点 上下文对象的子树。

        第一个匹配元素是什么?

        我们可以将document#uerySelectorAll 与相同的选择器一起使用,您可以看到数组中的第一个结果是&lt;div&gt;a1&lt;/div&gt;

        const result = Array.from(document.body.querySelectorAll('div > div:last-of-type'));
        
        console.log(result);
        <html>
        <body>
        <div>
            <div>a<div>a1</div></div>
            <div>b</div>
            <p>c</p>
            <div>d</div>
        </div>

        如何获得&lt;div&gt;d&lt;/div&gt;

        创建一个只匹配你想要的选择器:

        console.log(document.body.querySelector('body > div > div:last-of-type'));
        
        console.log(document.body.querySelector('p + div'));
        <html>
        <body>
        <div>
            <div>a<div>a1</div></div>
            <div>b</div>
            <p>c</p>
            <div>d</div>
        </div>

        【讨论】:

          【解决方案4】:

          如果要从初始容器 div 的 div 子项中进行选择,请为 div 指定类或 ID,例如 .container,然后将其选择为 document.body.querySelector('div.container &gt; div:last-of-type');

          您当前的代码是从作为任何其他 div 的最后一个 div 子级的 div 中选择的,您没有指定要专门查看容器 div 的子级

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2022-11-30
            • 2015-10-14
            • 2020-12-08
            • 1970-01-01
            • 2013-03-25
            • 2017-11-28
            • 2016-04-20
            • 1970-01-01
            相关资源
            最近更新 更多