views:

30514

answers:

8

So I know that you can do:

if ($(selector).length>0) {
    // Do something
}

But is there a more elegant method?

+70  A: 

Yes!

jQuery.fn.exists = function(){return jQuery(this).length>0;}

if ($(selector).exists()) {
    // Do something
}

There you go!

This is in response to: Herding Code podcast with Jeff Atwood

jakemcgraw
I just write: if( $(selector).length ){ ... } without the '> 0'
vsync
ditto.....what is the point in this?
redsquare
Your `$.fn.exists` example is really, really horrible, and I hope nobody uses it. You’re replacing a property lookup (cheap!) with two function calls, which are much more expensive—and one of those function calls recreates a jQuery object that you already have, which is just silly.
snover
@snover you're free to down vote it
jakemcgraw
@redsquare: Code readability is the best rationale for adding this sort of function on jQuery. Having something called `.exists` reads cleanly, whereas `.length` reads as something semantically different, even if the semantics coincide with an identical result.
quixoto
@quixoto, sorry but .length is a standard across many languages that does not need wrapping. How else do you interpret .length?
redsquare
In my opinion, it's at least one logical indirection from the concept of "a list length that is greater than zero" to the concept of "the element(s) I wrote a selector for exist". Yeah, they're the same thing technically, but the conceptual abstraction is at a different level. This causes some people to prefer a more explicit indicator, even at some performance cost.
quixoto
I'd keep the > 0, always been a fan of readability. It's my way of imposing my will on the idiomatic intentions of a language and its creators.
MrBoJangles
+4  A: 

You can use:

if ($(selector).is('*')) {
  // Do something
}

A little more elegant, perhaps.

Devon
This is too much for such a simple thing. see Tim Büthe answer
vsync
+41  A: 

if you used:

jQuery.fn.exists = function(){return ($(this).length > 0);}
if ($(selector).exists()) { }

you would imply that chaining was possible when it is not.

This would be better

jQuery.exists = function(selector) {return ($(selector).length > 0);}
if ($.exists(selector)) { }

EDIT

Just found this in the FAQ:

http://docs.jquery.com/Frequently_Asked_Questions#How_do_I_test_whether_an_element_exists.3F

if ( $('#myDiv').length ) { //do something }

EDIT 2

you could also use the following. If there are no values in the jQuery obj array then getting the first item in the array would return undefined.

if ( $('#myDiv')[0] ) { //do something }
Jon Erickson
The first method reads better. $("a").exists() reads as "if <a> elements exist." $.exists("a") reads as "if there exists <a> elements."
strager
true but again, you're implying that chaining is possible and if I tried to do something like $(selector).exists().css("color", "red") it wouldn't work and then I would be =*(
Jon Erickson
There are already methods that aren't chainable, like attr and data functions. I do see your point though and, for what it's worth, I just test for length > 0 anyways.
Matthew Crumley
That is very true Matthew, thanks for pointing that out, i guess it is just a matter of preference.
Jon Erickson
Even your second example isn't chainable...
Josh Stodola
Why on earth would you need to chain this? `$(".missing").css("color", "red")` already does the right thing… (i.e. nothing)
Ben Blank
First example ($('.mySelector').length) works fine, no need to create an exists() wrapper for it.
nickb
The 2nd edit.... if ( $('#myDiv')[0] ) {..... undefined index 0. You should not compare the result direct, since there is NO result. Instead you should.... if ( typeof $('#myDiv')[0] !='undefined' )...
Christian Sciberras
+2  A: 
if ( $('#myDiv').size() > 0 ) { //do something }

size() counts the number of elements returned by the selector

+22  A: 

In JavaScript, everythig is truthy or falsy and for numbers, 0 means false, everything else true. So you could write:

if ($(selector).length)

and you don't need that "> 0" part.

Tim Büthe
This is the best method, fastest and simplest.
Skone
A: 

I have found that sometimes .length throws an error, but [element locator].size() > 0 works reliably

Mad Halfling
A: 

.size() is deprecated.

Justin
False. No mention of deprecation is made [in the documentation](http://api.jquery.com/size/), save for a [comment thread](http://api.jquery.com/size/#comment-30970704) which mentions that "The idea of deprecating it has been kicked around before".
Ben Blank
A: 
pavsaund
This is doubly incorrect. `isEmptyObject` is a method on the `jQuery` object itself, not matched sets, and returns `false` for both empty and non-empty sets.
Ben Blank
ah, the syntax i exampled was obviously, wrong. And I see that it returns false for both empty and non-empty sets. I was convinced that it didn't though
pavsaund