规范
该函数的输入是两个选择器。这意味着没有预先存在的 DOM 元素,这是此问题的一个重要约束。该函数应该回答的问题是“Needle 匹配的所有元素都会被 Haystack 匹配吗?”换句话说,我试图确定 Needle 匹配的元素集是否代表 Haystack 匹配的元素集的子集。下面的示例表应该阐明规范:
Needle | Haystack | Matches? | Explanation / Counterexample
-----------------+------------------+----------+--------------------------------
div | * | yes | Any div is something.
div | div | yes | Any div is a div.
div | div:not(.classy) | no | <div class="classy">
div | .classy | no | <div>
div.classy | div | yes | Any classy div is a div.
div.classy | div.classy | yes | Any classy div is a classy div.
div.classy | div:not(.classy) | no | <div class="classy">
div.classy | .classy | yes | Any classy div is classy.
div:not(.classy) | div | yes | Any non-classy div is a div.
.classy | div | no | <span>
.classy | div.classy | no | <div>
:not(.classy) | div | no | <span>
div div | div | yes | Any nested div is a div.
div | div div | no | Not all divs are nested.
一个简单的解决方案是基于 Needle 创建一个临时 DOM 元素,并使用 Haystack 作为参数调用 document.querySelector()
。该解决方案将迭代列表,如果找到生成的元素,则返回 true
。注意事项:
- 仅仅因为与 Needle 匹配的一个元素恰好与 Haystack 匹配,并不意味着与 Needle 匹配的所有可能元素都将与 Haystack 匹配。使代表性元素尽可能通用是很困难的。
- 很难生成与 non-simple selector 匹配的元素,因为必须重新创建直到该元素的整个树才能容纳它。
- 将临时元素插入 DOM 中而不正确清理它们可能会干扰网站逻辑。
完整的解决方案应该避免创建临时 DOM 元素。理想情况下,该解决方案将依赖于渲染引擎的内置 CSS 匹配机制。如果解决方案使用特定于 vendor 的函数,则这些函数应该可以在其他浏览器的当前版本上以纯 JavaScript 重新创建(其中 IE10 可以被视为“当前”IE)。
动机
该函数的目的是在文档样式表中查询适用于与给定选择器匹配的元素的所有规则。例如,给定以下 CSS:
* {
color: yellow;
}
div {
background-color: black;
}
.classy {
margin: 5px;
}
人们会期望以下内容:
Selector | Matched rules
-----------+-----------------------------------------------------
div.classy | color: yellow; background-color: black; margin: 5px;
div | color: yellow; background-color: black;
.classy | color: yellow; margin: 5px;
一个简单的解决方案将逐 block 迭代文档样式表并在选择器上执行精确的字符串匹配。这些产生的规则比 CSS 引擎计算的规则少。完整的解决方案需要上一节中描述的功能。
类似问题
我相信this asker想要一个类似的解决方案,但问题不被理解。
感谢您的宝贵时间!
最佳答案
我认为如果没有文档为选择者提供一些背景信息,这是不可能的。很容易看出“div”是“*”的子集。然而,对于“div”和“.classy”等其他选择器来说就不那么容易了。如果每个 div 都有一个 classy 类并且没有其他元素具有该类,那么它们可能会返回完全相同的元素集。
类似地,如果没有 div 具有 classy 类,“div”和“div:not(.classy)”可能会返回完全相同的集合。
因此,在一般情况下,不可能确定一个选择器是否在没有文档的情况下返回另一个选择器的子集,尽管可以针对非常有限(微不足道?)的一组情况(例如,span.someClass 是跨度)。
关于javascript - 在 JavaScript 中,如何确定与给定 CSS 选择器匹配的所有元素都将与另一个给定 CSS 选择器匹配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22445510/