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

Do I really need to check if an element exists with jQuery?

本文关键字:是否 存在 元素 检查 jQuery 我真的需要      更新时间:2023-09-26

我最近遇到了一个问题,关于如何使用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。

与我共事的一个人说,正确的检查方法应该是:

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

他错了,至少在$( "#myDiv" ) &&部分是这样。jQuery的$(selector)总是返回一个对象,根据定义,该对象是真实的。因此,这部分毫无意义,并且毫无理由地重新查询DOM。

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

毫无理由地重新查询DOM是一种浪费,但在大多数情况下,这在任何可观察到的方面都无关紧要,尤其是对于像$("#myDiv")这样的ID选择器来说,它们被jQuery优化为对getElementById的调用(这非常快)。所以一方面,是的,这是浪费额外的工作。另一方面,现在的浏览器速度太快了,你可能有更大的事情要做。但这可能是额外的毫无意义的代码,这是更大的问题。

一般来说:jQuery是基于集合的。这意味着在没有元素的集合上进行的操作不是操作。例如:

$(".foo").addClass("bar");

如果DOM中没有.foo元素,则为no-op(不是错误)。

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

因此,基本上有三种情况:

  1. 你知道元素会在那里,所以检查毫无意义
    =>无检查

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

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


1这里有一个重要的警告:如果您调用的jQuery函数返回的不是jQuery对象(例如,val()offset()position()等),当您在空集上调用它时,它通常会返回undefinedtext()除外,它将返回""[text()在某些方面与其他函数不同;这是其中之一])。因此,即使在集合为空的情况下,编写天真地假设这些东西会返回您期望的结果的代码也会让您感到痛苦。

例如:

if ($(".foo").offset().top > 20)

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

但这很好:

$(".foo").closest(".bar").toggleClass("baz"):

因为即使没有.fooclosest()也会返回另一个空的jQuery集,对其调用toggleClass()是no-op。

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

var offset = $(".foo").offset();
if (offset && offset.top > 20)

同样,大多数访问者(不返回jQuery对象)都会这样做,包括val()offset()position()css()。。。

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

var $myDiv = $( "#myDiv" );
if ($myDiv && $myDiv.length) { ... }

然而,jQuery选择器总是返回一些,这将被解释为"truthy",因此

if ($('#myDiv')) { 

是一个毫无意义的检查。

与我共事的一个人说,正确的检查方法应该是:

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

这个说法是错误的。如果未找到$( "#myDiv" ).length,则对其进行的检查将简单地返回0。可以肯定的是,这里有一个代码示例,其中找到了一个id,并且没有第二个id

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

取决于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,因为如果它不存在,无论如何都不会发生任何事情。

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

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