On Thu, Aug 6, 2009 at 9:27 AM, Joshua Beall <joshbe...@gmail.com> wrote:

>
> On Aug 6, 8:26 am, "Richard D. Worth" <rdwo...@gmail.com> wrote:
> > You can include the pseudo-selector in the same selector, immediately
> after
> > the ID, like so:
> >
> > $("#myDiv:hidden").show();
> > $("#myDiv:visible").hide();
> >
> > Another option would be to use the filter method:
> >
> > $("#myDiv").filter(":hidden").show();
> > $("#myDiv").filter(":visible").hide();
> >
>
>
> That works--I had assumed that if I called something like $
> ("#myDiv:hidden").show(); when myDiv is visible, it would cause a
> problem "object not found" problem since #myDiv:hidden" should return
> nothing, and I then tried to call ".show()" on that "nothing" that was
> returned.


It doesn't return nothing, it returns a jQuery object with 0 elements. Any
method you call will do a .each (like a for loop) on that (empty) set, (not)
calling that method on 0 elements. In other words, that loop will never even
be entered.


>
> In Java/C# I would get a NullReferenceException if I tried something
> like this.  That's where I do most of my development so that's what I
> was expecting.


Annoying, huh? ;)


>
> But I am left asking, why *don't* I get some kind of "object not
> found" error?


This is one of my favorite features of jQuery. It's always safe to call a
jQuery method on a jQuery object. No need to worry about how many elements
may have been returned by your query. 0, 1, 100. It is indeed different than
many other environments, but not all. For example in SQL, if you run the
following query

SELECT * FROM People WHERE age > 42

you might get 0 results, or 1, or 15, or 178. No error if 0 results match
your query. It's still a perfectly valid query. Ok, so how about this one:

DELETE FROM People WHERE age > 42

It might delete 0 records, or 1, or 15, or 178. If you knew of a specific
record that needed to be deleted and 0 records got deleted, sure, that might
be an error. But if no People have an age > 21, there's no error to your
query deleting 0 records. It's doing just what it should. Nothing. That's
kind of how jQuery works. The Q and Query that SQL and jQuery share is no
coincidence.

The other comparison I like to make is to css, which is quite fitting since
jQuery uses css selectors. Imagine you've got a css rule that styles all
paragraphs with a red font:

p { color: red; }

If you've got 0 paragraphs on your page, does your css stop with an
exception? Do you have to do a try/catch around you css rule? No, because
it's declarative. It applies to anything it matches. If it doesn't apply to
anything, it has no effect, and doesn't complain. Same as jQuery, only that
you're applying behavior instead of styling.

But to *really* answer your question, why doesn't jQuery complain loudly if
you tell it to do something to nothing? Because you didn't. If you go back
to your example, it can help to read it backwards. Rather than reading it as
saying "find _this_ element, then call _this_ method on it (barf! element
not found)", you can read it as "hide any elements that are visible and that
have this id" or "show the element with this id if it's not currently
visible" That "if" in the last two translations I gave are implicit in your
query returning at least one element. The else case is do nothing, because
there's nothing to do to nothing. In either of these scenarios, would it
help you if it complained? Would it make your life easier if you had to be
sure to never call a method on an empty result set? That would mean no
chaining, since every method call would need to be safely wrapped in an if
or a try/catch. And at the end of the day your code wouldn't do any more or
less, it would just be less fun and more code to write. You only want to
hide the element if it's visible. You only want to show if it's not. So that
extra required code would just get in your way.

There's a word for this: unobtrusive.

But wait? What if you really *do* care if your query returned 0 results.
What if you want to do something different in this case. Compare .length to
0 in an if statement. That's a lot less common scenario.

Ok, that was a bit long. Sorry to anyone that made it this far :)

- Richard

Reply via email to