jQuery:.has()和:has()之间的细微差别

当与子选择器>一起使用时,jQuery的“has”的两个变体表现不同。

拿这个HTML:

 
Text

现在:

 $("div:has(>span)"); 

将它返回,同时:

 $("div").has(">span"); 

不会。 它是一个bug还是一个function? 比较这里: http : //jsfiddle.net/aC9dP/


编辑:这可能是一个错误或至少没有记录的不一致行为。

无论如何,我认为让子选择器始终作为一元运算符工作是有益的。 它使您能够执行其他需要自定义过滤function的操作 – 它允许您直接选择具有特定子项的元素:

 $("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) 。

发生这种情况是因为sizzle选择器正在查看所有具有跨越子项的Div:示例。 但是在.has示例中,它将所有DIV传递给.has(),然后查找不应该是独立选择的东西。 (“没有孩子”)。

基本上,:has()是选择的一部分,但.has()会传递这些div,然后从中重新选择。

理想情况下,您不使用这样的选择器。 选择器中的>可能是一个错误,因为它在语义上很尴尬。 注意:子操作员不应该是独立的。

Sizzle vs target.sizzle:

我一直在谈论jquery开发版本的v1.4.2 。

.has (jQuery第3748行)

描述: 将匹配元素集减少具有与选择器或DOM元素匹配的后代的元素集。

码:

  var targets = jQuery( target ); return this.filter(function() { for ( var i = 0, l = targets.length; i < l; i++ ) { if ( jQuery.contains( this, targets[i] ) ) { //Calls line 3642 return true; } } }); 

3642行涉及2008插件compareDocumentPosition ,但重要的是我们现在基本上只在这里运行两个jquery查询,其中第一个选择$("DIV")而下一个选择$(">span") (返回null),然后检查子项。

:has (jQuery第3129行)

描述:选择包含至少一个与指定选择器匹配的元素的元素

码:

return !!Sizzle( match[3], elem ).length;

它们是两个不同的工具,它们:使用100%的嘶嘶声,并且。使用传递给它的目标。

注意:如果您认为这是一个错误,请填写错误单。

我想你可能遇到了一个真正的错误。 问题可能在于您使用子选择器的方式。 正如user257493指出的那样,它并不意味着单独使用(或者至少我在文档中没有看到任何这样的例子。

看看这个。 如果你在.has()的子选择器之前添加一个* ,它突然起作用: http : //jsfiddle.net/Ender/FjgZn/

但是如果你在:has()选择器中执行相同的操作,它就会停止工作! 见这里: http : //jsfiddle.net/Ender/FjgZn/

这两者的实施方式肯定存在差异。