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

JavascriptJquery

Javascript Problem Overview


I recently had a question about how to correctly check if an element exists with jQuery. I found the answer from here:

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

In summary:

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

One guy I work with says the correct way to check should be:

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

Does it matter? I mean from a performance or latency wise, do they perform the same?

Also:

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

In these type of jQuery functions, it seems no if check is needed because they won't raise an error if #myDiv does not exist, correct?

For what it's worth, I am using jQuery 1.6.4.

Javascript Solutions


Solution 1 - Javascript

> One guy I work with says the correct way to check should be: > > if ($( "#myDiv" ) && $( "#myDiv" ).length ) { > //do something > }

He's wrong, at least in terms of the $( "#myDiv" ) && part. jQuery's $(selector) always returns an object, which by definition is truthy. So that part is pointless, and re-querying the DOM for no reason.

> I mean from a performance or latency wise, do they perform the same?

Re-querying the DOM for no reason is a waste, but most of the time it doesn't matter in any observable way, and especially not for ID selectors like $("#myDiv") which are optimized by jQuery into calls to getElementById (which is blazingly-fast). So on the one hand, yes, it's wasteful extra work. On the other hand, browsers are so fast these days that you probably have bigger fish to fry. But it's probably extra pointless code, which is the larger issue.

To the general point: jQuery is set-based. This means that operations on sets with no elements in them are no-ops. E.g.:

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

...is a no-op (not an error) if no .foo elements are in the DOM.

So check for length if and when you care whether you matched elements. If you don't care and just want to perform operations on them if they're there, just go ahead and do the operation (with one important caveat1).

So basically, there are three scenarios:

  1. You know the elements will be there, so the check is pointless
    => no check

  2. You don't know the elements will be there, but you don't care and just want to operate on them if they're there
    => no check

  3. You care whether the elements are there for some other reason
    => do the check


1 Here's the important caveat: If you're calling a jQuery function that returns something other than a jQuery object (for instance, val() or offset() or position(), etc.), when you call it on an empty set, it will typically return undefined (the exception is text(), which will return "" [text() is not like the others in several ways; this is one of them]). So writing code that naively assumes those things will return what you're expecting, even when the set is empty, will bite you.

So for example:

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

...will throw an error if there are no .foo elements, because offset() will return undefined, not an object.

But this is fine:

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

...because even if there are no .foo, closest() will return another empty jQuery set, and calling toggleClass() on it is a no-op.

So when dealing with an accessor that doesn't return a jQuery object, if you don't know for sure you're dealing with a set containing at least one element, you need more defensiveness, e.g.:

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

Again, most accessors (that don't return jQuery objects) do this, including val(), offset(), position(), css(), ...

Solution 2 - Javascript

It matters, and $( "#myDiv" ).length is better because it is not running document.getElementById('myDiv') twice. If you were caching the selector, it would matter much less:

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

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

However, jQuery selectors always return something that will be interpreted as "truthy", so

if ($('#myDiv')) { 

is a pointless check.

Solution 3 - Javascript

> One guy I work with says the correct way to check should be: > > > if ($( "#myDiv" ) && $( "#myDiv" ).length ) { > //do something > }

This statement is false. The check of $( "#myDiv" ).length would simply return 0 if it's not found. To be sure, here's a code example with both an id found, and a second id that's not present:

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>

Solution 4 - Javascript

Depends on what you're doing after the if statement.

Think of it like this. Any jquery selector call returns a jquery object that's basically an array extended with a bunch of different methods. When you call something like $(".my-elements").show() it'll loop over whatever elements $(".my-elements") returned and apply .show() to them then return that same jquery object which is how jquery chains.

If you're just doing chainable things then no, you don't need to do the if check. Because all the subsequent methods will just do a loop equivalent to for (var i=0; i<0; i++){ } which means nothing will happen. If you've got a big chain and you're running it in a big loop that needs to be very performant, you might want to do the if check, but generally it won't really matter from a performance standpoint.

If however, you're doing something that will throw an error or give you a bad result if the element doesn't exist then yes, use the if check. For instance

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

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

If div1 or div2 don't exist otherDiv will get it's top set to NaN which is probably not what you're going for. In this case you would want to verify that both div1 and div2 actually exist, but you still don't really have to check for otherDiv because if it doesn't exist nothing will happen anyway.

Solution 5 - Javascript

Is more simple to check if exists and , if we want more info from the object we will not receive null object error.

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionOPKView Question on Stackoverflow
Solution 1 - JavascriptT.J. CrowderView Answer on Stackoverflow
Solution 2 - JavascriptRob M.View Answer on Stackoverflow
Solution 3 - JavascriptDrew KennedyView Answer on Stackoverflow
Solution 4 - JavascripthobberwickeyView Answer on Stackoverflow
Solution 5 - JavascriptFlautarianView Answer on Stackoverflow