300

What is the best way to detect if a jQuery-selector returns an empty object. If you do:

alert($('#notAnElement'));

you get [object Object], so the way I do it now is:

alert($('#notAnElement').get(0));

which will write "undefined", and so you can do a check for that. But it seems very bad. What other way is there?

Ata Iravani
  • 2,146
  • 7
  • 29
  • 40
peirix
  • 36,512
  • 23
  • 96
  • 126

8 Answers8

519

My favourite is to extend jQuery with this tiny convenience:

$.fn.exists = function () {
    return this.length !== 0;
}

Used like:

$("#notAnElement").exists();

More explicit than using length.

Magnar
  • 28,550
  • 8
  • 60
  • 65
  • 2
    Why did you wrap 'this' inside a $() ? wouldn't 'this' in this context actually point to jQuery object ? – Adham Atta Mar 28 '11 at 11:25
  • 1
    I find that returning `this` is much more helpful than `true`. See my answer porting Rails' `presence` method. – Marc-André Lafortune Feb 26 '13 at 22:22
  • 5
    If you want to maintain the ability to chain, should the function return true, or if you would like to use this method to assign `this` to a variable, I would recommend [changing the return statement to what CSharp](http://stackoverflow.com/a/10861528/573634) has. – Hanna Nov 06 '13 at 22:52
  • 1
    Magnar, can you please explain how this "extension" function actually works? I'm assuming it's a Javascript concept and not a strictly JQuery concept. I looked into prototyping but I'm not sure if that applies here and why the syntax would be "$.fn." – KyleM Jul 30 '14 at 15:39
  • Sweet. Doesn't get any simpler than this. Tx – Jos Jun 09 '15 at 08:21
  • @magnar doesn't this result in 2 DOM traversals if you actually need to use the element for something? `if($("#anElement").exists()) { $("#anElement").doSomething(); }` – Adam Mar 07 '16 at 23:46
  • 3
    @Adam Yes. But in that case, you should just drop the exists-check, given how jQuery works. It will just not do something if there is no element matching the selector. – Magnar Mar 10 '16 at 07:15
  • @Adam If the function returns $this or false, you can do one traversal thusly: `let theThing = $("#anElement").exists(); if( theThing ) { theThing.doSomething(); }` -- assuming a use case where you need to check-then-do – Stephen R Jul 17 '19 at 15:52
209
if ( $("#anid").length ) {
  alert("element(s) found")
} 
else {
  alert("nothing found")
}
Joshua Pinter
  • 45,245
  • 23
  • 243
  • 245
duckyflip
  • 16,189
  • 5
  • 33
  • 36
76

The selector returns an array of jQuery objects. If no matching elements are found, it returns an empty array. You can check the .length of the collection returned by the selector or check whether the first array element is 'undefined'.

You can use any the following examples inside an IF statement and they all produce the same result. True, if the selector found a matching element, false otherwise.

$('#notAnElement').length > 0
$('#notAnElement').get(0) !== undefined
$('#notAnElement')[0] !== undefined
Evan Carroll
  • 78,363
  • 46
  • 261
  • 468
Jose Basilio
  • 50,714
  • 13
  • 121
  • 117
  • 1
    I use `.length` unless the code is hot. It's certainly the most clear with intent. Also, [`.size()`](http://api.jquery.com/size/) is deprecated and has been for years (since 1.8). I'm just going to edit your answer and remove that, feel free to add it back with a note but it's so old, I think it's better gone. – Evan Carroll Jan 21 '15 at 03:13
  • 2
    Technically it returns a jQuery object that contains no DOM nodes. Saying it returns an empty array isn't right. – Vigrant Apr 06 '17 at 19:53
39

I like to do something like this:

$.fn.exists = function(){
    return this.length > 0 ? this : false;
}

So then you can do something like this:

var firstExistingElement = 
    $('#iDontExist').exists() ||      //<-returns false;
    $('#iExist').exists() ||          //<-gets assigned to the variable 
    $('#iExistAsWell').exists();      //<-never runs

firstExistingElement.doSomething();   //<-executes on #iExist

http://jsfiddle.net/vhbSG/

CSharp
  • 629
  • 6
  • 6
  • 6
    @Ehsan Actually it's not a duplicate of the accepted answer...note that the accepted answer only returns true/false while this answer returns either *the original object* ("this") or false. This answer allows you to do additional stuff with the return value (such as additional function chaining) if it is non-false. – RSW Jun 10 '15 at 13:07
  • 1
    I have exactly the same code in my standard toolkit. This form is equivalent to object.presence in Rails and super useful in the fallthrough construct that @CSharp describes. – inopinatus Aug 27 '15 at 23:12
  • This is a good answer, but it would be helpful if you explain what happens if NONE of the tested elements exists. Short answer: `TypeError: firstExistingElement.doSomething is not a function`. You can wrap the entire variable assignment/test in an if() and only do something if an element is found.... – Stephen R May 02 '18 at 20:14
9

I like to use presence, inspired from Ruby on Rails:

$.fn.presence = function () {
    return this.length !== 0 && this;
}

Your example becomes:

alert($('#notAnElement').presence() || "No object found");

I find it superior to the proposed $.fn.exists because you can still use boolean operators or if, but the truthy result is more useful. Another example:

$ul = $elem.find('ul').presence() || $('<ul class="foo">').appendTo($elem)
$ul.append('...')
Scott C Wilson
  • 19,102
  • 10
  • 61
  • 83
Marc-André Lafortune
  • 78,216
  • 16
  • 166
  • 166
7

My preference, and I have no idea why this isn't already in jQuery:

$.fn.orElse = function(elseFunction) {
  if (!this.length) {
    elseFunction();
  }
};

Used like this:

$('#notAnElement').each(function () {
  alert("Wrong, it is an element")
}).orElse(function() {
  alert("Yup, it's not an element")
});

Or, as it looks in CoffeeScript:

$('#notAnElement').each ->
  alert "Wrong, it is an element"; return
.orElse ->
  alert "Yup, it's not an element"
nilskp
  • 3,097
  • 1
  • 30
  • 34
6

This is in the JQuery documentation:

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

  alert( $( "#notAnElement" ).length ? 'Not null' : 'Null' );
Daniel De León
  • 13,196
  • 5
  • 87
  • 72
0

You may want to do this all the time by default. I've been struggling to wrap the jquery function or jquery.fn.init method to do this without error, but you can make a simple change to the jquery source to do this. Included are some surrounding lines you can search for. I recommend searching jquery source for The jQuery object is actually just the init constructor 'enhanced'

var
  version = "3.3.1",

  // Define a local copy of jQuery
  jQuery = function( selector, context ) {

    // The jQuery object is actually just the init constructor 'enhanced'
    // Need init if jQuery is called (just allow error to be thrown if not included)
    var result = new jQuery.fn.init( selector, context );
    if ( result.length === 0 ) {
      if (window.console && console.warn && context !== 'failsafe') {
        if (selector != null) {
          console.warn(
            new Error('$(\''+selector+'\') selected nothing. Do $(sel, "failsafe") to silence warning. Context:'+context)
          );
        }
      }
    }
    return result;
  },

  // Support: Android <=4.0 only
  // Make sure we trim BOM and NBSP
  rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;

jQuery.fn = jQuery.prototype = {

Last but not least, you can get the uncompressed jquery source code here: http://code.jquery.com/

Devin Rhode
  • 23,026
  • 8
  • 58
  • 72