我真的需要检查一个元素是否存在与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这里有一个重要的警告:如果你调用的是一个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 }); }
如果div1
或div2
不存在otherDiv
将得到它的顶部设置为NaN
这可能不是你要去的。 在这种情况下,您需要validationdiv1
和div2
实际上是否存在,但是您仍然不需要检查otherDiv
因为如果它不存在,则无论如何都不会发生任何事情。
检查是否存在更简单,如果我们想从对象获取更多信息,我们将不会收到空对象错误。
if (!!$( "#myDiv" )) { //do something }