Bol*_*ock 32 javascript jquery jquery-selectors sizzle
显然,正如我在评论另一个答案时发现的那样,jQuery(而不是它的底层选择器引擎Sizzle)允许你将参数引用到:not()选择器和:has()选择器.即:
$('div:not("span")')
$('span:has("span")')
Run Code Online (Sandbox Code Playgroud)
在Selectors标准中,引号始终代表字符串,而不是选择器或关键字,因此引用参数:not()始终无效.这在选择器4中不会改变.
您还可以通过添加不受支持的CSS选择:nth-last-child(1) 器来查看它是非标准语法,例如导致选择器完全失败:
$('div:not("span"):nth-last-child(1)')
$('span:has("span"):nth-last-child(1)')
Run Code Online (Sandbox Code Playgroud)
在这里允许报价是否有任何理由,技术或其他方面?想到的唯一可能性是:
一致性:contains()允许引用和不引用的参数,如旧的选择器规范中所示.除了:contains()接受字符串/关键字,而不是选择器...
与自定义伪使用的实现保持一致$.expr[':'],始终允许引用和不引用的参数.
一致性和易用性移植到他们的方法同行.not()和.has()(只是删除或拆分外报价和改变冒号期?).
但我找不到任何支持或反对它们的消息来源.实际上,引用选择器参数本身的能力也没有在任何地方记录,引用和引用参数之间似乎没有任何区别:
$('div:not(span)')
$('span:has(span)')
Run Code Online (Sandbox Code Playgroud)
Wil*_*mer 30
这不是针对:not(...)与:has(...)selectors-实际上,在所有灒假点允许引用参数.伪参数的模式定义为:
pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:" + attributes + ")|[^:]|\\\\.)*|.*))\\)|)"
Run Code Online (Sandbox Code Playgroud)
这可在线发现91的sizzle.js作为831c9c48...
让我们添加一些缩进,使其更具可读性.不幸的是,这仍然是一个正则表达式,因此"更具可读性"仍然有很多不足之处:
pseudos = (
":(" + characterEncoding + ")" +
"(?:" +
"\\(" + // literal open-paren
"(?:" +
"(['\"])" + // literal open-quote
"((?:\\\\.|[^\\\\])*?)" + // handle backslash escaping
"\\2" + // close-quote
"|" + // - OR -
"(" +
"[^()[\\]]*" +
"|" +
"(?:" +
"(?:" + attributes + ")" +
"|" +
"[^:]" +
"|" +
"\\\\." +
")*" +
"|" +
".*" +
")" +
")" +
"\\)" + // literal close-paren
"|" + // ie, 'or nothing'
")"
);
Run Code Online (Sandbox Code Playgroud)
主要的一点是:在伪属性中可以在参数周围使用单引号或双引号.正确处理反斜杠转义,因此任何字符串都可以作为参数传入.请注意,"string"部分与上面的regexp中的"selector"部分在同一匹配索引中结束; 所以,简而言之,这就是为什么他们被平等对待:因为pseudos模式不区分两者.编辑:从jQuery 1.8.2开始,带引号和不带引号的参数更明确地等效.我似乎无法在jQuery git存储库中找到此代码[帮助将不胜感激],但是由google托管的版本为1.8,具有a0f48b6ad5322b35383ffcb6e2fa779b8a5fcffc的sha1sum,具有
"PSEUDO":在线功能4206,它明确检测到"引用"和"不加引用的"论据,并确保它们都在同一个地方结束.该逻辑也没有伪的类型("位置"或不)其中参数是区分.
由于Sizzle使用Javascript字符串来启动选择过程,因此当参数传递给函数时,"string"和"selector"之间没有区别.做出这种区分是可能的,但据我所知,实际需要的东西总是很容易从最基本的上下文中确定(即:使用什么类型的伪),所以没有真正的理由做出区分.(如果有任何我不知道的模棱两可的情况,请在评论中更正 - 我想知道!).
那么,如果字符串和选择器之间缺乏区别仅仅是一个实现细节,为什么伪如:eq(...)明确拒绝这样的选择呢?
答案很简单:事实并非如此.至少,不是jQuery 1.8.1.[ 编辑:从jQuery 1.8.2开始,它根本没有."位置"伪的论点可以像其他任何东西一样引用.以下关于1.8.1实施细节的说明留作历史好奇心]
诸如:eq(...)以下的功能实现为:
"eq": function( elements, argument, not ) {
var elem = elements.splice( +argument, 1 );
return not ? elements : elem;
}
Run Code Online (Sandbox Code Playgroud)
在:eq(...)接收参数时,它仍然是一个裸参数(引号和全部)的形式.与:not(...)此不同,这个论点没有经过一个compile(...)阶段.无效参数的"拒绝"实际上是由于快捷方式转换
+argument,这将导致NaN任何带引号的字符串(反过来,它永远不会匹配任何东西).这是另一个实现细节,尽管在这种情况下是一个"正确"的行为(同样,据我所知.在这种情况下,这些函数的非数字参数是否应该匹配?)
编辑:从jQuery 1.8.2开始,事情已经有所重构,"位置"伪不再接受"原始"参数.结果,引用的参数现在被接受:eq(...)等.这个变化似乎是另一个错误修复的副作用,因为在af8206ff的更改日志中没有提到对引用参数的支持..这是为了修复处理中的错误:first和:lastjQuery bug#12303.使用git bisect和相对简单的phantomjs脚本找到此提交.值得注意的是,在e89d06c4中重写Sizzle之后,Sizzle不会仅仅为选择器静默失败:eq("3"),实际上会抛出异常.这应该被视为:eq("3")支持不是预期行为的更多证据.
确实存在关于自定义过滤器的基本原理,在某些情况下,它们的参数可以被认为是字符串,有时候也可以被视为选择器,无论它们表面看起来如何,这取决于它们被评估的方法......但是这很多就要接近了迂腐的.应该说,在调用函数时,至少没有区别会使事情更简单,无论它们代表什么,它们都会期望字符串表示.
简而言之,整个情况可以被认为是一个实现细节,并且根植于选择器首先作为字符串传递的事实(如何将它们带入Sizzle?).
| 归档时间: |
|
| 查看次数: |
1083 次 |
| 最近记录: |