views:

259

answers:

4
+5  Q: 

jQuery subtleties

Community wiki. At least I think it's worthy of that. I've always been interested in some of the inner workings of jQuery, and a great question prompted this.

I'm not talking about cool stuff you can do with jQuery but more subtleties of how it works. Maybe links to helpful posts could come in here.

One example is that $() is interchangeable with $(document) as can be seen from the source:

jQuery.fn = jQuery.prototype = {
    init: function( selector, context ) {
        // Make sure that a selection was provided
        selector = selector || document;

Any more?

+4  A: 

While the documentation only mentions triggering events on a selected set of elements:

$('button').trigger('click');

You can actually trigger an event on all elements (including objects outside the DOM such as document and window) by calling the jQuery.event.trigger function:

jQuery.event.trigger('click');

This is useful especially when you add custom events with $('element').bind('event', function) and want to trigger it on all elements that are bound to it. Note that this in the event handler function will refer to the individual element, as usual.

This is how jQuery's Ajax events work.

Blixt
I've used this for a nice little event driven app. I'm a fan.
geowa4
you mention eventing, do you know of a quick way to get all the elements with a click event handler set?
geowa4
I believe you'd have to loop through the `jQuery.cache` collection and check if each object has an `events` property. If it does, that jQuery object (which represents one DOM element) has one or more events. The `events` property is a lookup object where the names represent event type ("click" etc.) and the values are a list of handlers.
Blixt
+1. I didn't know this, thanks! Though I am wondering why would I ever want to fire click events for all the events on the page. George, could you tell us how you used this particular feature?
SolutionYogi
Nope, click isn't a good example. But I used it in my jquery.hash plugin: http://blixt.org/js/jquery.hash.js Note the event on the `div#log` element.
Blixt
A: 

You should look into how jQuery binds event handling to objects.

geowa4
+5  A: 

A subtlety which I often mix up is the difference between the iterator function's arguments to $.each and $.grep, which are reversed:

$.grep's form:

$.grep(["a","b","c"],function(item,i){
  console.log(i,item);
});

Grep takes a function with the item as the first argument, and the counter as the second.

$.each's form:

$.each(["a","b","c"],function(i,item){
  console.log(i,item);
});

Each takes a function with the counter as the first argument, and the item as the second.

Mixing these up can lead to some fun bugs :)

Another subtlety that comes up for some beginners is that of result sets vs. single elements:


$(selector)

Returns a jQuery object, which could contain a number of DOM elements.


$(selector)[0] or $(selector).get(0)

Returns the first result as an actual DOM element.


$(selector).eq(0) or $($(selector).get(0))

Returns the DOM element wrapped in a jQuery object so that we can do stuff like:

$(selector).eq(0).addClass("deleted").fadeOut();
Maciek
It's worth mentioning that `$('li')[0]` works as a substitute for `$('li').get(0)`. It's also worth mentioning that `$('li').eq(0)` returns the element wrapped as a jQuery object.
Blixt
+2  A: 
SolutionYogi
Great explanation :-)
David Archer