views:

83

answers:

3

I have been learning some of the more detailed loopholes of JS here and there, and have a few things I need to get help on.

;(function($){
    $.fn.makeRed1 = function() {
        return $.each(this, function() {
            $(this).css('background-color', '#FF0000');
        });
    }
})(jQuery)


;(function($){
    $.fn.makeRed2 = function() {
        $(this).css('background-color', '#FF0000');
    }
})(jQuery)

Both of these work correctly. Why?

Anyone who talks about writing plugins always says to use the 'return each' method. What is the reason? I need someone to tell me exactly what happens when each of these methods are used, so I can understand the flow.

Thanks.

+1  A: 

Without the each loop, your function will only operate of the first selected element. While, using each will allow you to manipulate multiple selected elements with a single method call.

Ending your function by returning this is what facilitates the jQuery style method chaining.

Using:

return this.each(function() { /* do stuff */ });

is just shorthand for:

this.each(function(){ /* do stuff */);
return this;

Re: comment: The reason why not using each works in your example, is because the .css() method uses each internally. If you were actually doing something custom, like manually manipulating the DOM, or native Element objects, in your example plugin, you'd have to use each to apply your changes to all selected elements.

jason
Ok, the return makes sense, however the non-each method still works across all elements. That is what confused me, I assumed the each was to transverse multiple elements, but no.
Spot
+2  A: 

In the first case you are explicitly returning the results of the each function. The each function iterates over the matching elements and applies the callback specified to each one. The return value of the function is the jQuery object matching the selected elements. This allows you to chain your newly defined function in the way that users of jQuery would expect and apply additional jQuery functions to the selected elements.

In the second case, you have a simple statement that applies the same callback, albeit directly. Because you don't return anything, you aren't able to chain with this function. This breaks the jQuery paradigm.

tvanfosson
Ok, but since all elements are affected whether you use 'each' or not, why use 'each'? If my understanding is correct `return $(this).css('background-color', '#FF0000');` would still pass the jQ object back for chaining. I'm more interested as to the use of 'each' or not.
Spot
Consider a more complex plugin/function which consists of multiple statements, many of which are not chained together and some of which may not return jQuery. Using the each syntax provides a convenient mechanism to wrap all of this up in a method that allows you to write your code without the need to keep a reference to the original jQuery collection.
tvanfosson
Ah ok, thank you very much.
Spot
+1  A: 

Basically the return $.each statement, allows you to preserve the elegant jQuery chaining paradigm, let's say, you have two custom jQuery functions:

;(function($){
    $.fn.makeRed = function() {
        return $.each(this, function() {
            $(this).css('background-color', '#FF0000');
        });
    }

    $.fn.makeBold = function() {
        return $.each(this, function() {
            $(this).css('font-weight', 'bold');
        });
    }
})(jQuery)

You could write the following statement for example, without any problem:

$(selector).makeRed().makeBold().show();
CMS