【问题标题】: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 > div:last-of-type') 返回<div>a1</div>,而不是<div>d</div>。
我认为document.body.querySelector('div > div:last-of-type') 应该与document.body.querySelector('div > div:nth-of-type(3)') 相同,后者返回<div>d</div>。
总结一下我的问题:
为什么document.body.querySelector('div > div:last-of-type') 返回<div>a1</div>,而不是<div>d</div>?是bug吗?
选择<div>d</div>的正确方法是什么?
【问题讨论】:
标签:
javascript
html
dom
css-selectors
【解决方案1】:
-
为什么document.body.querySelector('div > div:last-of-type') 返回<div>a1</div>,而不是<div>d</div>?是bug吗?
不,这不是错误。原因有两个:
- 如果选择器匹配多个元素,
querySelector() 仅返回第一个匹配元素。
- 选择器的范围不限于调用
querySelector() 方法的元素。
由于<div>a1</div> 是第一个与div > div:last-of-type 匹配的元素,这就是您的代码返回的内容。
-
选择<div>d</div>的正确方法是什么?
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 与相同的选择器一起使用,您可以看到数组中的第一个结果是<div>a1</div>。
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>
如何获得<div>d</div>?
创建一个只匹配你想要的选择器:
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 > div:last-of-type');
您当前的代码是从作为任何其他 div 的最后一个 div 子级的 div 中选择的,您没有指定要专门查看容器 div 的子级