jQuery:.has() 和 :has() 之间的细微差别
当与子选择器 >
一起使用时,jQuery 的“has”的两个变体的行为不同。
拿这个 HTML:
<div>
<span>Text</span>
</div>
Now:
$("div:has(>span)");
会返回它,而 while:
$("div").has(">span");
不会。这是一个错误还是一个功能?比较这里: http://jsfiddle.net/aC9dP/
编辑: 这可能是一个错误或至少是未记录的不一致行为。
无论如何,我认为让子选择器始终作为一元运算符工作是有益的。它使您能够执行一些需要自定义过滤器功能的操作 - 它允许您直接选择具有某些子级的元素:
$("ul:has(>li.active)").show(); // works
$("ul").has(">li.active)").show(); // doesn't work, but IMHO it should
而不是:
$("ul").filter(function () {
return $(this).children("li.active").length > 0;
}).show();
我已经打开 为此提供 jQuery 票证 (7205)。
When used with the child selector >
, the two variants of jQuery's "has" behave differently.
Take this HTML:
<div>
<span>Text</span>
</div>
Now:
$("div:has(>span)");
would return it, while:
$("div").has(">span");
would not. Is it a bug or a feature? Compare here: http://jsfiddle.net/aC9dP/
EDIT: This may be a bug or at least undocumented inconsistent behavior.
Anyway, I think it would be beneficial to have the child selector consistently work as an unary operator. It enables you to do something that otherwise would require a custom filter function — it lets you directly select elements that have certain children:
$("ul:has(>li.active)").show(); // works
$("ul").has(">li.active)").show(); // doesn't work, but IMHO it should
as opposed to:
$("ul").filter(function () {
return $(this).children("li.active").length > 0;
}).show();
I've opened a jQuery ticket (7205) for this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
发生这种情况是因为 sizzle 选择器正在查看 :has 示例中具有 span 子级的所有 Div。但在 .has 示例中,它将所有 DIV 传递给 .has(),然后 .has() 查找不应该是独立选择的内容。 (“没有孩子”)。
基本上, :has() 是选择的一部分,但是 .has() 传递了这些 div,然后从中重新选择。
理想情况下,您不要使用这样的选择器。的>出现在选择器中可能是一个错误,因为它在语义上很尴尬。注意:子运算符并不意味着是独立的。
Sizzle 与 target.sizzle:
我总是在谈论 jquery 开发版本的 v1.4.2。
.has(jQuery 第 3748 行)
描述:将匹配元素集减少为具有与选择器或 DOM 元素匹配的后代的元素。
代码:
第 3642 行与 2008 插件 compareDocumentPosition 相关,但这里重要的是我们现在基本上只是在这里运行两个 jquery 查询,其中第一个选择
$("DIV")
,下一个选择$(">span")
(返回null),然后我们检查孩子。:has (jQuery 第 3129 行)
描述:选择至少包含一个与指定选择器匹配的元素的元素。
代码:
return !!Sizzle( match[3], elem ).length;
它们是两个不同的工具,:has 使用 100% 的 sizzle,而 .has 使用传递给它的目标。
注意:如果您认为这是一个错误,请填写错误单。
This happens because the sizzle selector is looking at all Div's that have span children in the :has example. But in the .has example, it's passing all DIV's to the .has(), which then looks for something that shouldn't be a stand-alone selection. ("Has children of nothing").
Basically, :has() is part of the selection, but .has() gets passed those divs and then re-selects from them.
Ideally, you don't use selectors like this. The > being in the selector is probably a bug, as it's semantically awkward. Note: the child operator isn't meant to be stand-alone.
Sizzle vs target.sizzle:
I'm always talking about v1.4.2 of jquery development release.
.has (line 3748 of jQuery)
Description: Reduce the set of matched elements to those that have a descendant that matches the selector or DOM element.
Code:
Line 3642 relates to a 2008 plugin compareDocumentPosition, but the important bit here is that we're now basically just running two jquery queries here, where the first one selects
$("DIV")
and the next one selects$(">span")
(which returns null), then we check for children.:has (line 3129 of jQuery)
Description: Selects elements which contain at least one element that matches the specified selector.
Code:
return !!Sizzle( match[3], elem ).length;
They are two differnt tools, the :has uses sizzle 100%, and .has uses targets passed to it.
Note: if you think this is a bug, go fill out the bug ticket.
我认为您可能遇到了一个真正的错误。问题可能在于您使用子选择器的方式。正如 user257493 指出的那样,它并不意味着可以单独使用(或者至少我在文档中没有看到任何示例。
不过请检查一下。如果您在
.has()
中的子选择器,突然它起作用了:http://jsfiddle. net/Ender/FjgZn/但是,如果您在
:has()
选择器中执行相同的操作,它就会停止工作,请参阅此处:http://jsfiddle.net/Ender/FjgZn/
这些方式似乎肯定有所不同两项已实施。
I think you may have hit upon a genuine bug. The problem may lie in the way you are using the child selector. As user257493 pointed out, it's not meant to be used on its own (or at least I don't see any examples of that in the documentation.
Check this out though. If you add a
*
before the child selector in the.has()
, suddenly it works: http://jsfiddle.net/Ender/FjgZn/But if you do the same thing in the
:has()
selector, it stops working! See here:http://jsfiddle.net/Ender/FjgZn/
There definitely seems to be difference in the way these two are implemented.