Javascript 为什么:not()和:has()等函数伪函数允许引用参数?
显然,正如我在评论时发现的,jQuery(而不是它的底层选择器引擎)允许您引用Javascript 为什么:not()和:has()等函数伪函数允许引用参数?,javascript,jquery,jquery-selectors,sizzle,Javascript,Jquery,Jquery Selectors,Sizzle,显然,正如我在评论时发现的,jQuery(而不是它的底层选择器引擎)允许您引用:not()选择器以及:has()选择器的参数 在中,引号始终代表字符串,而不是选择器或关键字,因此将参数引用到:not()总是无效的 您还可以通过添加诸如:nth last child(1): 在这里允许报价有什么好的理由,技术上的还是其他的?我想到的唯一可能性是: 与的一致性:contains(),它允许带引号和不带引号的参数,如中所示。除了:contains()接受字符串/关键字,而不是选择器 与使用$.exp
:not()
选择器以及:has()
选择器的参数
在中,引号始终代表字符串,而不是选择器或关键字,因此将参数引用到:not()
总是无效的
您还可以通过添加诸如:nth last child(1)
:
在这里允许报价有什么好的理由,技术上的还是其他的?我想到的唯一可能性是:
- 与
,它允许带引号和不带引号的参数,如中所示。除了的一致性:contains()
接受字符串/关键字,而不是选择器:contains()
- 与使用
实现自定义伪码的一致性,该伪码始终允许带引号和不带引号的参数$.expr[':']
- 一致性和易于移植到方法对应项
和.not()
(只需删除或拆分外部引号并将冒号更改为句点?).has()
$('div:not(span)')
$('span:has(span)')
这不是特定于
:不是(…)
和:具有(…)
选择器-实际上,所有的伪
在Sizzle中允许引用参数。伪参数的模式
定义如下:
pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:" + attributes + ")|[^:]|\\\\.)*|.*))\\)|)"
可以在网上找到
让我们给它添加一些缩进,让它更具可读性。
不幸的是,这仍然是一个regexp,所以“可读性更高一些”
还有很多需要改进的地方:
pseudos = (
":(" + characterEncoding + ")" +
"(?:" +
"\\(" + // literal open-paren
"(?:" +
"(['\"])" + // literal open-quote
"((?:\\\\.|[^\\\\])*?)" + // handle backslash escaping
"\\2" + // close-quote
"|" + // - OR -
"(" +
"[^()[\\]]*" +
"|" +
"(?:" +
"(?:" + attributes + ")" +
"|" +
"[^:]" +
"|" +
"\\\\." +
")*" +
"|" +
".*" +
")" +
")" +
"\\)" + // literal close-paren
"|" + // ie, 'or nothing'
")"
);
这样做的主要好处是:可以使用单引号或双引号
在伪属性中围绕参数使用。反斜杠转义是
正确处理,因此任何任意字符串都可以作为
论点请注意,“字符串”部分在相同的匹配索引中结束
作为上述regexp中的“选择器”部分;简言之,这就是原因
它们被同等对待:因为pseudos
模式没有
区分两者编辑:从jQuery 1.8.2开始,参数
带引号和不带引号更明确地等效。我看不出来
要在jQueryGit存储库中找到这段代码[非常感谢您的帮助],但是,有一个
“PSEUDO”:4206行上的
函数,它明确检测
“引用”和“未引用”参数之间的差异,并确保
两者都在同一个地方。此逻辑不区分
在参数所属的伪(“位置”或非位置)类型之间
因为
Sizzle使用Javascript字符串启动选择过程,
当使用参数时,“字符串”和“选择器”之间没有区别
传递给函数。做出这样的区分是非常困难的
可能,但就我所知,真正想要的总是
从最基本的上下文(即:什么类型的
正在使用pseudo),因此没有真正的理由
区别。(如有任何不明确之处,请在评论中更正。)
我不知道的情况——我想知道!)
因此,如果字符串和选择器之间缺乏区别是一个问题
仅仅是实现细节,为什么像:eq(…)
这样的伪函数显式
拒绝这样的选择
答案很简单:事实并非如此。至少,在jQuery中不是这样
1.8.1. [edit:从jQuery 1.8.2开始,它一点也没有
“位置”伪符号可以像其他任何东西一样引用
关于1.8.1的实施细节的注释保留为
[历史好奇心]
诸如:eq(…)
等功能的实现方式如下:
"eq": function( elements, argument, not ) {
var elem = elements.splice( +argument, 1 );
return not ? elements : elem;
}
当:eq(…)
收到参数时,它仍处于
纯参数的形式(引号和全部)。与:not(…)
不同,此
参数没有经过编译(…)
阶段。拒绝
无效参数实际上是由于快捷方式转换导致的
+参数
,对于任何带引号的字符串(在
旋转,从不匹配任何东西)。这是另一个实现
细节,尽管在本例中是一个“正确”的行为
如我所知,是否存在非数值参数用于此类
功能实际上应该匹配吗?)
编辑:从jQuery 1.8.2开始,事情已经进行了一些重构,并且
“位置”伪对象不再接收“原始”参数。因此,
引用的参数现在在:eq(…)
等中被接受。这一变化
似乎是另一个错误修复的副作用,因为在旨在修复的changelog中没有提到对引用参数的支持。此提交是使用git bisect和找到的。值得注意的是,在中重写Sizzle之后,Sizzle不仅会对选择器(如:eq(“3”)
)无声地失败,实际上还会引发异常。这应该被视为进一步证明:eq(“3”)
支持不是预期行为的证据
关于自定义过滤器,确实有一些基本原理,它们的参数
在某些情况下可能被认为是字符串,有时可能被认为是
选择器,不管它们表面看起来像什么,取决于
评估它们的方法。。。但这一点正在接近
书呆子。只要说没有区别就足够了
至少在调用函数时会使事情变得更简单
不管它们可能表示什么,除了字符串表示
简言之,整个情况可以被视为一种实施
细节,并植根于选择器
pseudos = (
":(" + characterEncoding + ")" +
"(?:" +
"\\(" + // literal open-paren
"(?:" +
"(['\"])" + // literal open-quote
"((?:\\\\.|[^\\\\])*?)" + // handle backslash escaping
"\\2" + // close-quote
"|" + // - OR -
"(" +
"[^()[\\]]*" +
"|" +
"(?:" +
"(?:" + attributes + ")" +
"|" +
"[^:]" +
"|" +
"\\\\." +
")*" +
"|" +
".*" +
")" +
")" +
"\\)" + // literal close-paren
"|" + // ie, 'or nothing'
")"
);
"eq": function( elements, argument, not ) {
var elem = elements.splice( +argument, 1 );
return not ? elements : elem;
}