How/why 是“ *[attribute^="string" ” 有效的查询选择器吗? (JS 错误?)

How/why is “ *[attribute^="string" ” a valid querySelector? (JS bug?)

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

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

如您所见,我忘记关闭属性访问器,使用 ],像这样:

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

奇怪的是,它奏效了!

Edit - no I didn't, I actually ran the correct CSS selector:

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

... but as mentioned in the comments apparently this further typo also works!

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

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

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

Uncaught DOMException: Failed to execute 'querySelectorAll' on 'Document': 'a[onclick^="ajaxLoad(", a tc-link' is not a valid selector.

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

起初我以为这是一个语言怪癖但修改了问题:任何人都可以算出哪个级别(DOM?V8?呃.. webkit?我不太了解来龙去脉) 相关的 Javascript/browser 代码,以及从哪里可以获得 reported/fixed?

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

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

首先,让我们分析一个错误的选择器列表:

  • 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="(缺少"]))

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

上工作

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

这可能是一个错误或功能(又名,作为功能提交的令人尴尬的错误)以软化 CSS 引擎的渴望。这也会影响 jQuery,因为 jQuery 仅在 document.querySelectorAll() 不存在或抛出异常时才使用 Sizzle

再过一段时间我们就能找到更多。

免责声明:

这种行为不应该被依赖并且可能在未来改变。
这都是基于 invalid 选择器和无效语法(比如一些针对旧版本的 IE CSS Hacks)。 所有 上面列表中的工作选择器违反规范。

作为示例给出的 'unfixed' 选择器 (a,) works in jQuery,但这与这个问题无关。本质上,jQuery 将执行它作为 a.

大多数浏览器接受缺少的右括号的原因是它们都遵循来自 CSS specification. There is a discussion about this on the Chromium bugtracker; here's the relevant excerpt from the comment 的相同算法,该算法将错误关闭为 WontFix:

When you parse the string 'a[b=c' (from the example link), the CSS parser turns that into:

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

The fact that the square-bracket block was unclosed is lost. You can think of this as the parser "auto-closing all unclosed blocks". If you're using a spec-compliant parser, it is literally impossible to detect an unclosed block unless you do a separate ad hoc parsing on your own just for that purpose.

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