我真的需要检查一个元素是否存在与jQuery?

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

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(''); 

在这些types的jQuery函数中, if需要检查,看起来没有,因为如果#myDiv不存在,它们不会引发错误,是正确的?

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

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

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

他错了,至less在$( "#myDiv" ) &&部分方面。 jQuery的$(selector) 总是返回一个对象,它的定义是truthy。 所以这一部分是毫无意义的,无故重新查询DOM。

我的意思是从性能或延迟明智,他们执行相同的?

重新查询DOM没有任何理由是很浪费的,但大多数情况下不会以任何明显的方式影响,特别是不会像$("#myDiv")这样的IDselect器被jQuery优化成调用getElementById (这是非常快)。 所以一方面是的,这是浪费额外的工作。 另一方面,现在浏览器如此之快,你可能会有更大的鱼来炒。 但是这可能是无意义的代码,这是更大的问题。

总的来说:jQuery是基于集合的 。 这意味着在其中没有元素的集合上的操作是没有操作的。 例如:

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

如果没有.foo元素在DOM中,那么…是一个no-op(不是错误)。

所以,如果你关心你是否匹配元素,请检查length 。 如果你不在乎,只想在他们身上执行操作,那就继续操作(有一个重要的注意事项1 )。

所以基本上有三种情况:

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

  2. 你不知道元素会在那里,但你不在乎,只是想在他们身上操作
    =>没有检查

  3. 你在意这些元素是否有其他原因
    =>做检查


1这里有一个重要的警告:如果你调用的是一个jQuery函数,它返回的不是jQuery对象(例如, val()offset()position()等),当你在一个空集,它通常会返回undefined (例外是text() ,这将返回"" [ text()是不是像其他人在几个方面,这是其中之一])。 所以编写那些天真地假定那些东西会返回你所期望的代码,即使当这个集合是空的,也会咬你的。

举个例子:

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

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

但是这很好:

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

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

所以在处理一个不返回jQuery对象的访问器的时候,如果你不确定是否正在处理一个包含至less一个元素的集合,那么你需要更多的防御性,比如:

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

再次,大多数访问器(不返回jQuery对象)做到这一点,包括val()offset()position()css() ,…

它很重要, $( "#myDiv" ).length是更好的,因为它没有运行document.getElementById('myDiv')两次。 如果你cachingselect器,那么重要性就会小很多:

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

但是,jQueryselect器总是返回一些将被解释为“truthy”的东西,所以

 if ($('#myDiv')) { 

是一个毫无意义的检查。

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

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

这个陈述是错误的。 $( "#myDiv" ).length的检查只会返回0如果没有find。 可以肯定的是,下面是一个代码示例,其中包含一个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语句之后正在做什么。

像这样想。 任何jqueryselect器调用返回一个jquery对象,基本上是一个数组扩展与一堆不同的方法。 当你调用类似于$(".my-elements").show()它会遍历任何元素$(".my-elements")返回并将.show()返回给它们,然后返回相同的jquery对象是如何jQuery链。

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

但是,如果你正在做的事情会抛出一个错误,或者如果元素不存在,给你一个坏的结果是的,使用if检查。 例如

 function addHeight() { var height1 = $("#div1").height(), height2 = $("#div2").height(); $("#otherDiv").css({ top: height1 + height2 }); } 

如果div1div2不存在otherDiv将得到它的顶部设置为NaN这可能不是你要去的。 在这种情况下,您需要validationdiv1div2实际上是否存在,但是您仍然不需要检查otherDiv因为如果它不存在,则无论如何都不会发生任何事情。

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

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