Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't jQuery bomb if your selector object is invalid?

Was recently using some code along the lines of

$("#divMenuContainer:visible").hide("explode"); 

However after some time spent trying to get it to work I realized my selector was referencing a div that didnt exist.

The result of the query was simply that it didn’t execute.

Obviously this is by design, could anyone explain the logic of why this design choice was made rather than raise some sort of exception?

Not trying to criticise just trying to understand.

like image 436
Maxim Gershkovich Avatar asked Sep 14 '10 14:09

Maxim Gershkovich


People also ask

What is a valid jQuery selector?

jQuery selectors are used to "find" (or select) HTML elements based on their name, id, classes, types, attributes, values of attributes and much more. It's based on the existing CSS Selectors, and in addition, it has some own custom selectors. All selectors in jQuery start with the dollar sign and parentheses: $().

How jQuery selectors are executed?

If dealing with more than two selectors in a row then your last selectors are always executed first. For example, jQuery will first find all the elements with class “. list” and then it will select all the elements with the id “second”.

What is the slowest selector in jQuery?

Class selectors are the slowest selectors in jQuery.

What is the main difference between selectors and filters jQuery?

jQuery selector selects all elements based on the elements name given by you. jQuery filter( ) adds further detail to the selected elements by specifying the criteria of selection.


2 Answers

Think of it as a query, which it is. You are asking for all "records" (DOM elements) that match your criteria. The result is a set of zero records.

It then loops over your zero records and applies the action to them. :)

If you did the same thing with SQL, or an array, it would behave the same way in most languages. A collection of zero records is not an error state.

var things = $("invalid selector");  $("p").text("The object is valid: " + things + " but has " + things.length + " elements.")
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>    <p></p>
like image 184
Matt Sherman Avatar answered Oct 12 '22 23:10

Matt Sherman


There are a few good reasons here, "chainability" is the main drive, the ability to write very terse code by chaining has to throw no errors to work seemlessly, for example:

$("#divMenuContainer:visible").hide("explode").add("#another").fadeIn(); 

Each object in the chain, even if it references no DOM elements may have more added later, or let's take another example:

$("#divMenuContainer:visible").live("click", function() { ... }); 

In this case we don't care about any of the elements the selector found, we care about the selector itself. Here's another:

$("#divMenuContainer:visible").find(".child").hide("explode").end().fadeOut(); 

Even if there are no children, we may want to hop back in the chain afterwards, continuing to use the .prevObject reference to go back up the chain.

There are dozens of distinct cases like this that show the benefits of the library being the way it is. As for the why, from interviews of John Resig, who is the creator of jQuery, he states that's just how it worked out. He was after code as terse as he could get it, and the chaining model is what came out of hat, it just happens to have a lot of benefits as well, the example above are just a few of those.

To be clear, I'm not saying every attribute of chaining is a good one, there are just many upsides to it.


Let's take this page as an example, what if we had something like this:

$(".comment").click(replyToFunction); 

Should that fail because there aren't any comments yet? Well no not really, that's expected, I wouldn't want an error here...if the element exists do it, if not don't. My point is, at least in my experience, not throwing an error because of a missing element is tremendously more useful than throwing one.

The selector in your question, the #IDselector is a very special case where you expect only a single element, so maybe you could argue it should fail there...but then that wouldn't be consistent with other selectors, and you want a library to be consistent.

With pretty much any other selector you expect 0-many elements, so failing when you don't find any elements would be significantly less desirable in most situations, even more so in the cases like .live() above.

like image 20
Nick Craver Avatar answered Oct 13 '22 00:10

Nick Craver