开发者

Why does $('#id') return true if id doesn't exist?

开发者 https://www.devze.com 2022-12-17 17:05 出处:网络
I always wondered why jQuery returns true if I\'m trying to find elements by id selector that doesnt exist in the DOM structure.

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:

<div id="one">one</div>

<script>
    console.log( !!$('#one') ) // prints true
    console.log( !!$('#two') ) // is also true! (empty jQuery object)
    console.log( !!document.getElementById('two') ) // print开发者_JS百科s false
</script>

I know I can use !!$('#two').length since length === 0 if the object is empty, but it seems logical to me that a selector would return the element if found, otherwise null (like the native document.getElementById does).

F.ex, this logic can't be done in jQuery:

var div = $('#two') || $('<div id="two"></div>');

Wouldnt it be more logical if the ID selector returned null if not found?

anyone?


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().


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


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.


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())
{

}


You could check the .length property of the jQuery object. Like this:

if($("#two").length > 0) { // exists...

} else { // doesn't exist

}


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号