我真的需要检查jQuery是否存在元素吗?

OPK*_*OPK 62 javascript jquery

我最近有一个关于如何正确检查jQuery是否存在元素的问题.我从这里找到答案:

https://learn.jquery.com/using-jquery-core/faq/how-do-i-test-whether-an-element-exists/

综上所述:

if ( $( "#myDiv" ).length ) {
    // Do something
}
Run Code Online (Sandbox Code Playgroud)

我工作的一个人说正确的检查方法应该是:

if ($( "#myDiv" ) && $( "#myDiv" ).length ) {
    // Do something
}
Run Code Online (Sandbox Code Playgroud)

有关系吗?我的意思是从性能或延迟方面来说,它们是否表现相同?

也:

$( "#myDiv" ).show();
$( "#myDiv" ).hide();
$( "#myDiv" ).val('');
Run Code Online (Sandbox Code Playgroud)

在这些类型的jQuery函数中,似乎不需要if检查,因为如果#myDiv不存在则不会引发错误,对吗?

对于它的价值,我使用的是jQuery 1.6.4.

T.J*_*der 101

我工作的一个人说正确的检查方法应该是:

if ($( "#myDiv" ) && $( "#myDiv" ).length ) {
    //do something
}
Run Code Online (Sandbox Code Playgroud)

他是错的,至少在这$( "#myDiv" ) &&部分方面.jQuery $(selector) 总是返回一个对象,根据定义它是真实的.所以这部分毫无意义,并且无缘无故地重新查询DOM.

我的意思是从性能或延迟方面来说,它们是否表现相同?

无缘无故地重新查询DOM是一种浪费,但大多数情况下它无论以任何可观察的方式都无关紧要,尤其不适用于$("#myDiv")通过jQuery优化调用的ID选择器getElementById(这是非常快速的).所以一方面,是的,这是浪费的额外工作.另一方面,浏览器如此之快,以至于你可能有更大的鱼来炒.但它可能是额外毫无意义的代码,这是一个更大的问题.

总的来说:jQuery是基于集合的.这意味着对没有元素的集合的操作是no-ops.例如:

$(".foo").addClass("bar");
Run Code Online (Sandbox Code Playgroud)

如果.fooDOM中没有元素,则...是无操作(不是错误).

因此,检查您length是否以及何时关心是否匹配元素.如果您不在乎并且只是想在它们上面执行操作,那么请继续操作(有一个重要的警告1).

基本上,有三种情况:

  1. 你知道元素会在那里,所以检查是没有意义的
    =>没有检查

  2. 你不知道的元素会在那里,但你不在乎,只是想对他们进行操作,如果他们在那里
    =>不检查

  3. 你关心元素是否存在其他原因
    =>做检查


1这里是重要的警告:如果你调用一个jQuery函数,返回其他的东西比一个jQuery对象(例如,val()offset()position()等),当你把它在一个空集,它通常会返回undefined(例外情况是text(),将返回""[ text()与其他人不同的几种方式;这是其中之一]).因此,编写天真地假设这些东西的代码将返回您期望的内容,即使该集合为空,也会咬你.

例如:

if ($(".foo").offset().top > 20)
Run Code Online (Sandbox Code Playgroud)

...如果没有.foo元素,将抛出错误,因为offset()将返回undefined,而不是对象.

但这很好:

$(".foo").closest(".bar").toggleClass("baz"):
Run Code Online (Sandbox Code Playgroud)

...因为即使没有.foo,closest()也会返回另一个空的jQuery集,并且调用toggleClass()它是一个无操作.

因此,在处理不返回jQuery对象的访问器时,如果您不确定要处理包含至少一个元素的集合,则需要更多的防御性,例如:

var offset = $(".foo").offset();
if (offset && offset.top > 20)
Run Code Online (Sandbox Code Playgroud)

同样,大多数存取(即不返回jQuery的对象)做到这一点,其中包括val(),offset(),position(),css(),...

  • 小心这个:'......只是想在他们在那里时执行操作......' - 在0匹配集上执行操作是正常的,对*执行任何操作*是错误的.示例:`$('#fdsafasdfasd').val()`不是错误,但是`$('#NotOnThePage').val().trim()`如果没有匹配则会抛出错误.对于一些人来说这可能是显而易见的,但我发现自己不时会忘记它. (10认同)

Rob*_* M. 28

这很重要,而且$( "#myDiv" ).length更好,因为它没有运行document.getElementById('myDiv')两次.如果你正在缓存选择器,那就更不重要了:

var $myDiv = $( "#myDiv" );

if ($myDiv && $myDiv.length) { ... }
Run Code Online (Sandbox Code Playgroud)

但是,jQuery选择器总是会返回一些被解释为"truthy"的东西,所以

if ($('#myDiv')) { 
Run Code Online (Sandbox Code Playgroud)

是一个毫无意义的检查.


Dre*_*edy 5

我工作的一个人说正确的检查方法应该是:

if ($( "#myDiv" ) && $( "#myDiv" ).length ) {
    //do something 
}
Run Code Online (Sandbox Code Playgroud)

这句话是错误的.如果找不到,检查$( "#myDiv" ).length将简单地返回0.可以肯定的是,这是一个代码示例,其中包含一个已id找到的,另一个id不存在:

console.log("Count of #myDiv's found: " + $("#myDiv").length);
console.log("Count of #AnotherMyDiv's found: " + $("#AnotherMyDiv").length);
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<div id="myDiv"></div>
Run Code Online (Sandbox Code Playgroud)