“ *[attribute^="string" ” 如何/为啥是有效的 querySelector? (JS错误?)

Posted

技术标签:

【中文标题】“ *[attribute^="string" ” 如何/为啥是有效的 querySelector? (JS错误?)【英文标题】:How/why is “ *[attribute^="string" ” a valid querySelector? (JS bug?)“ *[attribute^="string" ” 如何/为什么是有效的 querySelector? (JS错误?) 【发布时间】:2015-05-21 03:56:40 【问题描述】:

所以,这可能是一个错误...我输入了错误的 CSS 路径,以检查已处理为具有以 "ajaxLoad(" 开头的特定 onclick 函数的元素

document.querySelectorAll( 'a[onclick^="ajaxLoad("' )

如你所见,我忘了用]关闭属性访问器,就像这样:

document.querySelectorAll( 'a[onclick^="ajaxLoad(]"' )

奇怪的是,它起作用了!

编辑 - 不,我没有,我实际上运行了正确的 CSS 选择器:

document.querySelectorAll( 'a[onclick^="ajaxLoad("]' )

...但正如 cmets 中提到的,显然这个进一步的错字也有效!

这显然是无效的。当我添加另一种类型的链接时,我发现了它,类 tc-link,我想知道我是否可以像在 CSS 样式表中那样链接它:

document.querySelectorAll('a[onclick^="ajaxLoad(", a.tc-link')

答案是你可以关闭那个括号,但是不能当这个错字留在里面。

未捕获的 DOMException:无法在“文档”上执行“querySelectorAll”:“a[onclick^="ajaxLoad(”,tc-link' 不是有效的选择器。

它适用于 ^=$=*=,据我所知,在 Firefox 或 Opera 中不会发生(而且我没有任何其他浏览器可以测试)。

起初我认为这是一个语言怪癖,但修改后的问题是:任何人都可以计算出 javascript/浏览器代码的哪个级别(DOM?V8?呃.. webkit?我不太了解其中的来龙去脉)这与它有关,在哪里可以报告/修复?

【问题讨论】:

IE 的行为似乎与 Chrome 相同。并不是每天都有两个最糟糕的浏览器在完全相同的事情上搞砸。请注意,您使用] 关闭的方式不正确,因为您在" 之前而不是之后有],但奇怪的是它也有效。另外值得补充的是,它在所有浏览器中的 CSS 中都正确失败。 哈哈,我实际上回去并添加了那个例子来说明 - 第一次在我的控制台中我确实这样运行它,但是它们都工作得多么奇怪! @collapsar:问题是您所说的错误更正不应该发生。给定的选择器无效,句号,应该抛出一个 SYNTAX_ERR。 @collapsar:看起来我的原始评论并不清楚 - 它似乎没有被视为令牌交换,只是属性值中的一个额外的 ]。它可能与正确的元素不匹配,但我的意思是说它不会导致 SYNTAX_ERR,原因与完全没有它不会导致的原因相同。 这个错误太奇怪了!在此页面上使用 a[onclick="" 有效。什么?甚至a[onclick="][onclick 也有效!!! (注意最后缺少的"])简而言之,a[onclick=" 也可以! 【参考方案1】:

这主要是基于意见的,离确定的答案还很遥远。

浏览器极其复杂。完毕!没有什么是可以预测的。

首先,我们来分析一个故障选择器列表:

a[onclick^="ajaxLoad("(缺少]a[onclick^="ajaxLoad(]"(缺少]a[onclick=""(缺少]a[onclick="][onclick(根据您的需要,缺少"] 或缺少"]a[onclick=""][onclick(缺少]a[onclick="(缺少"]a[onclick(缺少]a:not([onclick](缺少)a:not([onclick(缺少])a:not([onclick="(缺少"])a:nth-child(5):not([onclick="(缺少"])a:-webkit-any(:not([onclick="(缺少"]))

到目前为止,这是找到的列表。我可以确认这些可以在 Windows 7 上的 Google Chrome 41.0.2272.89m 上运行。

注意到模式了吗?很简单:Chrome 仍然可以使用那里的选择器通过填充基本的缺失字符来匹配元素,但最后 only ! 缺少的东西是如此可预测的,它不需要太多的努力来修复。 但并非每个选择器都可以/将被“固定”(例如:a,,可以通过添加 * 来固定)。

这可能是一个 bug 或一个特性(又名,一个作为特性提交的令人尴尬的 bug),以缓和 CSS 引擎的急切性。这也会影响 jQuery,因为 jQuery 仅在 document.querySelectorAll() 不存在或抛出异常时才使用 Sizzle。

随着时间的推移,我们可以找到更多。

免责声明:

这种行为不应被依赖,并且可能在未来发生变化。 这一切都基于 invalid 选择器和无效语法(如旧版本的一些 IE CSS Hacks)。 所有上面列表中的工作选择器不符合规范。

作为示例给出的“未固定”选择器 (a,) works 在 jQuery 中,但这与这个问题无关。本质上,jQuery 会将其执行为a

【讨论】:

【参考方案2】:

大多数浏览器接受缺少的右括号的原因是它们都遵循来自CSS specification 的相同算法。 Chromium bugtracker 上对此进行了讨论;以下是 comment 的相关摘录,它以 WontFix 的形式关闭了该错误:

当您解析字符串“a[b=c”(来自示例链接)时,CSS 解析器会将其转换为:

IDENT(A)
SIMPLE [ BLOCK:
    IDENT(B)
    DELIM(=)
    IDENT(C)

方括号块未闭合的事实丢失了。您可以将其视为解析器“自动关闭所有未关闭的块”。如果您使用的是符合规范的解析器,则实际上不可能检测到未关闭的块,除非您为此目的自行进行单独的临时解析。

(我知道我在这里挖掘一个老问题,但由于这仍然是 comes up 不时,链接和解释可能有用。)

【讨论】:

你知道他们为什么不接受它作为 CSS 规则的一部分吗?

以上是关于“ *[attribute^="string" ” 如何/为啥是有效的 querySelector? (JS错误?)的主要内容,如果未能解决你的问题,请参考以下文章