“ *[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错误?)的主要内容,如果未能解决你的问题,请参考以下文章