2010-01-16 94 views
29

我总是想知道为什么如果我试图通过id结构中不存在的id选择器来查找元素,jQuery将返回true。

像这样:

<div id="one">one</div> 

<script> 
    console.log(!!$('#one')) // prints true 
    console.log(!!$('#two')) // is also true! (empty jQuery object) 
    console.log(!!document.getElementById('two')) // prints false 
</script> 

我知道我可以使用!!$('#two').length因为长度=== 0,如果对象是空的,但它似乎是合乎逻辑,我认为,如果发现了一个选择将返回该元素,否则null (就像原生document.getElementById一样)。

F.ex,这个逻辑不能在jQuery的完成:

var div = $('#two') || $('<div id="two"></div>'); 

难道不更符合逻辑,如果如果没有找到ID选择返回null?

有人吗?

回答

46

这种行为选择,因为否则的jQuery会定期抛出NullReference例外

几乎所有的jQuery函数返回一个jQuery对象周围有问题的DOM元素的包装,所以你可以使用点符号。

$("#balloon").css({"color":"red"}); 

现在想象$("#balloon")回到。这意味着$("#balloon").css({"color":"red"}); 会抛出一个错误,而不是像你期望的那样默默无闻。

因此,您只能使用.length.size()

+3

我也在想这是其中一个原因。但以这种方式抑制错误真的是一个好主意吗?如果没有找到id,我确定想知道抛出错误的位置而不是调试每个链。 – David 2010-01-16 15:41:41

+1

如果您使用id选择器,这可能是您想要的行为,因为id(通常)是唯一的。但是如果您使用类选择器来关闭页面上的所有对话框/弹出窗口,该怎么办?您不希望函数仅仅因为用户当前没有打开任何对话框而抛出错误。你会希望它默默无闻。 – Dan 2010-01-17 12:59:48

+2

JavaScript没有任何称为NullReference异常的东西。也许你的意思是'ReferenceError'? – 2010-01-17 14:15:52

8

这是jQuery的只是如何工作的。

$("#something")

对象0 =#DIV东西长度= 1周的jQuery 1.2.6 =

$("#nothing")

对象长度= 0的jQuery 1.2.6 =

5

可以接近通过访问元素的长度来做你想做的事情,并与三元运算符结合:

console.log(!!$('#notfound').length); // false 
console.log(!!$('#exists').length); // true 
var element= $('#notfound').length ? $('#notfound') : $('#exists'); 
console.log(element.attr('id')); // outputs 'exists' 

至于问题的心脏:

难道不更符合逻辑,如果如果没有找到该ID 选择返回null?

不,不做事的方式JQuery的 - 即支持JQuery的语句链接:

$('#notfound').hide("slow", function(){ 
     jQuery(this) 
     .addClass("done") 
     .find("span") 
      .addClass("done") 
     .end() 
     .show("slow", function(){ 
      jQuery(this).removeClass("done"); 
     }); 
    }); 

即使notfound不存在这个代码将不会停止执行脚本运行。如果初始选择器返回null,则必须添加if/then块以检查null。如果addClass,find,end和show方法返回null,则必须添加if/then块以检查每个方法的返回状态。链接是处理动态类型语言(如Javascript)中的程序流程的绝佳方式。

2

你可以检查jQuery对象的.length财产。就像这样:

if($("#two").length > 0) { // exists... 

} else { // doesn't exist 

} 
+1

这是很好的一个。它实际上可以缩短:'if($(“#two”)。length)'也应该这样做。 – miek 2010-01-16 13:58:02

0

总之,您可以将jQuery选择器的返回值看作包含0..n个元素的组,但从不为null。

你大概什么真正感兴趣的是$("#two")[0],这将给你通过选择返回的第一个实际元素。

+0

'$(“#two:first”)'仍然会返回一个jQuery对象。 – James 2010-01-16 11:43:12

+0

谢谢J-P,我纠正了。更新了答案。 – miek 2010-01-16 13:55:39

3

因为为Javascript它是一个定义的对象因此不假它返回真,jQuery将总是给你不管该元件是否被找到或没有一个新的对象 - 然而数组长度将是零,例如

$("span").length

如果你没有<span>,这将是零,但它可能是1或更多。

您可以编写自己的插件,以避免重复,如果语句,一个jQuery插件,像我一样的this one。这是很容易做到:

(function($) 
{ 
     /* Checks if a jQuery object exists in the DOM, by checking the length of its child elements. */ 
     $.fn.elementExists = function() 
     { 
       ///  <summary> 
       ///  Checks if a jQuery object exists in the DOM, by checking the length of its child elements. 
       ///  </summary> 
       ///  <returns type="Boolean" /> 
       return jQuery(this).length > 0; 
     }; 
})(jQuery); 

用法:

if ($("#someid").elementExists()) 
{ 

} 
相关问题