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

时间:2016-08-03 18:31:13

标签: javascript jquery

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

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

总结:

if ( $( "#myDiv" ).length ) {
    // Do something
}

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

if ($( "#myDiv" ) && $( "#myDiv" ).length ) {
    // Do something
}

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

此外:

$( "#myDiv" ).show();
$( "#myDiv" ).hide();
$( "#myDiv" ).val('');

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

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

5 个答案:

答案 0 :(得分:99)

  

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

if ($( "#myDiv" ) && $( "#myDiv" ).length ) {
    //do something
}

他错了,至少就$( "#myDiv" ) &&部分而言。 jQuery' s $(selector) 总是返回一个对象,根据定义,该对象是真实的。所以这部分毫无意义,无缘无故地重新查询DOM。

  

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

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

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

$(".foo").addClass("bar");
如果DOM中没有.foo个元素,那么

...是一个无操作(不是错误)。

因此,如果您关心是否匹配元素,请检查length。如果你不在乎并且只想对他们进行操作如果他们在那里,那就继续进行操作(有一个重要的警告 1 )。

基本上,有三种情况:

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

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

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

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

    例如:

    text()
    如果没有if ($(".foo").offset().top > 20) 元素,

    ...会抛出错误,因为.foo将返回offset(),而不是对象。

    但这很好:

    undefined

    ...因为即使没有$(".foo").closest(".bar").toggleClass("baz"): .foo也会返回另一个空的jQuery集,并在其上调用closest()是无操作。

    因此,当处理一个没有返回jQuery对象的访问器时,如果你不确定你是否正在处理一个包含至少一个元素的集合,那么你需要更多的防御性,例如:

    toggleClass()

    同样,大多数访问者(不会返回jQuery对象)执行此操作,包括var offset = $(".foo").offset(); if (offset && offset.top > 20) val()offset()position(),... < / p>

答案 1 :(得分:28)

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

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

if ($myDiv && $myDiv.length) { ... }

然而,jQuery选择器总是返回某些,它将被解释为&#34; truthy&#34;,所以

if ($('#myDiv')) { 

是一个毫无意义的检查。

答案 2 :(得分:5)

  

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

if ($( "#myDiv" ) && $( "#myDiv" ).length ) {
    //do something 
}

这句话是错误的。如果找不到,则$( "#myDiv" ).length的检查只会返回0。可以肯定的是,这是一个代码示例,同时找到id和第二个id不存在:

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

答案 3 :(得分:3)

取决于if语句后你正在做什么。

这样想。任何jquery选择器调用都会返回一个jquery对象,它基本上是一个用一堆不同方法扩展的数组。当你调用像$(".my-elements").show()这样的东西时,它会循环遍历返回的任何元素$(".my-elements")并将.show()应用于它们然后返回相同的jquery对象,这就是jquery链的方式。

如果您只是做可连接的东西,那么不,您不需要进行if检查。因为所有后续方法都只会执行相当于for (var i=0; i<0; i++){ }的循环,这意味着什么都不会发生。如果你有一个大链并且你在一个需要非常高效的大循环中运行它,你可能想要进行if检查,但从性能角度来看通常并不重要。

但是,如果元素不存在,那么你正在做一些会抛出错误或给你一个错误结果的东西,那么使用if检查。例如

function addHeight() {
  var height1 = $("#div1").height(),
      height2 = $("#div2").height();

  $("#otherDiv").css({ top: height1 + height2 });
}

如果div1div2不存在,otherDiv会将其设置为NaN,这可能不是您的目标。在这种情况下,您需要验证div1div2是否确实存在,但您仍然不必检查otherDiv,因为如果它不存在则不会发生任何事情无论如何。

答案 4 :(得分:-1)

检查是否存在更简单,如果我们想从对象获得更多信息,我们将不会收到空对象错误。

if (!!$( "#myDiv" )) {
    //do something
}