I always wondered why jQuery returns true if I\'m trying to find elements by id selector that doesnt exist in the DOM structure.
Like this:
In short, you could think of the jQuery selector return value as a group containing 0..n elements, but never being null.
What you're probably really interested in is $("#two")[0]
, which will give you the first actual element returned by the selector.
You can come close to doing what you want by accessing the length the element, and combine with the ternary operator:
console.log(!!$('#notfound').length); // false
console.log(!!$('#exists').length); // true
var element= $('#notfound').length ? $('#notfound') : $('#exists');
console.log(element.attr('id')); // outputs 'exists'
As to the heart of the question:
Wouldnt it be more logical if the ID selector returned null if not found?
No, not for the JQuery way of doing things - namely, to support chaining of JQuery statements:
$('#notfound').hide("slow", function(){
jQuery(this)
.addClass("done")
.find("span")
.addClass("done")
.end()
.show("slow", function(){
jQuery(this).removeClass("done");
});
});
Even though notfound
doesn't exist this code will run without stopping script execution. If the initial selector returns null, you'll have to add in an if/then block to check for the null. If the addClass, find, end and show methods return null, you'll have to add an if/then block to check the return status of each. Chaining is an excellent way to handle program flow in a dynamically typed language like Javascript.
This behaviour was chosen because otherwise jQuery would regularly throw NullReference Exceptions
Almost all jQuery functions return a jQuery object as a wrapper around the Dom elements in question, so you can use dot notation.
$("#balloon").css({"color":"red"});
Now imagine $("#balloon")
returned null. That means that $("#balloon").css({"color":"red"});
would throw an error, rather than silently doing nothing as you would expect.
Hence, you just gotta use .length
or .size()
.
You could check the .length
property of the jQuery object. Like this:
if($("#two").length > 0) { // exists...
} else { // doesn't exist
}
This is just how jQuery works.
$("#something")
Object 0=div#something length=1 jquery=1.2.6
$("#nothing")
Object length=0 jquery=1.2.6
It returns true because to Javascript it is a defined object therefore not false, and jQuery will always give you a new object regardless of whether the element is found or not - however the array length will be zero, e.g.
$("span").length
If you have no <span>
, this will be zero, but it could be 1 or more.
You can write your own plugin to avoid repeated if statements as a Jquery plugin, like I did for this one. It's fairly easy to do:
(function($)
{
/* Checks if a jQuery object exists in the DOM, by checking the length of its child elements. */
$.fn.elementExists = function()
{
/// <summary>
/// Checks if a jQuery object exists in the DOM, by checking the length of its child elements.
/// </summary>
/// <returns type="Boolean" />
return jQuery(this).length > 0;
};
})(jQuery);
Usage:
if ($("#someid").elementExists())
{
}