Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么:not()和:has()等函数伪函数允许引用参数?_Javascript_Jquery_Jquery Selectors_Sizzle - Fatal编程技术网

Javascript 为什么:not()和:has()等函数伪函数允许引用参数?

Javascript 为什么:not()和:has()等函数伪函数允许引用参数?,javascript,jquery,jquery-selectors,sizzle,Javascript,Jquery,Jquery Selectors,Sizzle,显然,正如我在评论时发现的,jQuery(而不是它的底层选择器引擎)允许您引用:not()选择器以及:has()选择器的参数 在中,引号始终代表字符串,而不是选择器或关键字,因此将参数引用到:not()总是无效的 您还可以通过添加诸如:nth last child(1): 在这里允许报价有什么好的理由,技术上的还是其他的?我想到的唯一可能性是: 与的一致性:contains(),它允许带引号和不带引号的参数,如中所示。除了:contains()接受字符串/关键字,而不是选择器 与使用$.exp

显然,正如我在评论时发现的,jQuery(而不是它的底层选择器引擎)允许您引用
: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;
}