为啥 jQuery 3 不能识别属性选择器中的“#”字符?

Posted

技术标签:

【中文标题】为啥 jQuery 3 不能识别属性选择器中的“#”字符?【英文标题】:Why can't jQuery 3 identify the '#' character in an attribute selector?为什么 jQuery 3 不能识别属性选择器中的“#”字符? 【发布时间】:2016-11-19 20:03:24 【问题描述】:

我刚刚尝试将我的应用程序切换到 jQuery 3。我正在经历一些测试并且一切都按预期工作,直到我遇到了一个在选择器中使用“#”符号的应用程序。我有一段 jQuery 看起来像这样:

var $existingFilter = $container.find('.filterFeedItem[data-component-type=#somefilter]');

使用 jQuery 3 我得到一个错误:

jquery-3.0.0.js:1529 Uncaught Error: Syntax error, 
unrecognized expression: .filterFeedItem[data-component-type=#somefilter]

有谁知道为什么 jQuery 不能再解析包含这个符号的选择器?

【问题讨论】:

尝试用引号包裹#somefilter 【参考方案1】:

注意,更改显然发生在 2.0 版,因为 2.1.3 版使用选择器返回元素

var $existingFilter1 = $container.find('.filterFeedItem[data-component-type=#somefilter]');

jsfiddle https://jsfiddle.net/f8nej922/2/

虽然无法在jQuery 2.2 and 1.12 Released 文档中找到对更改的具体参考或描述。

作为@BoltClock 的noted,更改与Selector: Remove "#" exception for identifier tokens 有关。


您可以使用\\ 转义# 字符;属性选择器的引用值;或使用$.escapeSelector()

var $existingFilter = $container
                      .find('.filterFeedItem[data-component-type=\\#somefilter]');

var $existingFilter = $container
                      .find('.filterFeedItem[data-component-type="#somefilter"]');

var $existingFilter = $container
                      .find('.filterFeedItem[data-component-type=' 
                       + $.escapeSelector('#somefilter') + ']');

jsfiddle https://jsfiddle.net/f8nej922/4/

【讨论】:

我将此标记为正确 - 可靠的答案,感谢您的提琴。之前实际上没有使用过 $.escapeSelector 。我最终选择了不需要“#”符号的解决方案。一般来说,这可能是不好的做法——我只是按标签过滤,所以这对这种情况来说有点道理。谢谢! “不确定更改是否与选择器有关:删除标识符标记的 '#' 异常?”当然是 - 它在发行说明中链接到。但修复本身在Sizzle's codebase - 发布说明链接到包含测试套件的 jQuery 主 repo 中的变更集,而不是 Sizzle 本身。 @BoltClock 建议编辑?或编辑 Answer 以反映指向文档和代码更改的正确路径。 @Robert:这里使用 $.escapeSelector 是不正确的——你最终会转义 整个 选择器字符串,而不仅仅是属性值。你一般只在事先不知道属性值的情况下才使用 $.escapeSelector,例如如果它来自用户输入。 @guest271314: $.escapeSelector('.filterFeedItem[data-component-type=#somefilter]') 转义整个事情,导致\.filterFeedItem\[data-component-type\=\#somefilter\]。您应该只使用它来转义属性值。所以是的,你需要连接。【参考方案2】:

jQuery's documentation,属性值:

可以是有效标识符或带引号的字符串。

有效的标识符是任何有效的 css 标识符:

https://www.w3.org/TR/CSS21/syndata.html#value-def-identifier

在 CSS 中,标识符(包括元素名称、类和 ID) 选择器)只能包含字符 [a-zA-Z0-9] 和 ISO 10646 字符 U+00A0 及更高,加上连字符 (-) 和下划线 (_);它们不能以数字、两个连字符或后面的连字符开头 一个数字。标识符还可以包含转义字符和任何 ISO 10646 字符作为数字代码(参见下一项)。例如, 标识符“B&W?”可以写成“B\&W\?”或“B\26 W\3F”。

由于您想使用#,您需要转义或引用该值:

                         //Note the quotes v --------- v
.find('.filterFeedItem[data-component-type="#somefilter"]');

【讨论】:

坚定的回答帕特里克,因为小提琴,我把它给了guest271314。谢谢! 这并不能解释为什么 jQuery 将选择器视为过去 10 年有效。

以上是关于为啥 jQuery 3 不能识别属性选择器中的“#”字符?的主要内容,如果未能解决你的问题,请参考以下文章

jQuery 属性名称选择器中的通配符?

如何处理jQuery选择器中的特殊符号

为啥日期选择器中的日期格式没有改变?

jQuery属性的名称选择器中的通配符?

为啥 jQuery 在选择器中链接 .attr() 时只选择一个元素?

jQuery的选择器中的通配符