views:

34

answers:

1

I have an extension going like:

$.fn.crazything = function() {
    var self = $(this);
    // do some crazy stuff
    return self;
}

And when I call it like:

$("div.crazydiv").crazything();

It works, but only on the first matching div. If I have more than one div on the page, I need to do:

$("div.crazydiv").each(function(i) { $(this).crazything (); });

Why is this, and how can I rewrite my extension to work on multiple divs?

+5  A: 

Most jQuery plugins use this pattern which handles your crazy stuff:

(function($) {
  $.fn.crazything = function() {
    // allow setup on jQuery objects that conatin multiple elements:
    return this.each(function() {
      // this function is called once for each element in the jQuery object
      var self = $(this);
      // do some crazy stuff
    });
  };
})(jQuery);
gnarf
Outstanding! Someone needs to come up with a clever name for such a pattern. The "How did I live before jQuery Pattern"?
Wells
Great example. Please don't omit the "(function($) {" at the beginning and the "})(jQuery);" at the end -- if a plugin doesn't include this pattern, the projects I work on can't use it.
Drew Wills
@Wells: It is nothing special. Inside the function `this` refers to a collection of jQuery objects. So it makes sense that you have to iterate over it...
Felix Kling
The "return this.each(fn(x))" is the critical portion here. The original code is finding the first div found in all selected divs (as a group), rather than each selected div individually. The this.each iterates through each selected div.
Ender
I correct, it is not a collection of *jQuery* objects but *DOM* objects.
Felix Kling