views:

33

answers:

1

I'm working my way through the O'Reilly jQuery Cookbook. On p. 100 there is an example where I don't get one detail. I'm in my first week of looking at jQuery, so that's no surprise, but I'm hoping someone can clarify.

The function is a toggle with a few bells & whistles:

onValue and offValue are both Booleans, and must have opposite senses, and it might have been clearer to have only one of them, but the idea is to accommodate something where (for example) name is "disable". the optional on, also a Boolean, lets caller use this as a "set" instead of a "toggle"

jQuery.fn.toggleAttr = function (name, onValue, offValue, on) {
    function set($element, on) {
        var value = on ? onValue : offValue;
        return value == null ? $element.removeAttr(name) : $element.attr(name, value);
    }
    return on !== undefined ?
        // next line is where I'm confused
        set(this, on) : 
        this.each(function (i, element) {
             var $element = $(element);
             set($element, $element.attr(name) !== onValue);
        });
};

How is set( this, on ) working here? It seems to be working on the list of elements, but something needs to happen to each element, and I don't see what would cause any iteration. I'd have expected something more like the on === undefined case, something like:

        this.each (function( i, element ) {
            set( $(element), on);
        )}

So, am I missing something?

A: 

When on is not set then the toggleAttr function loops through each of the elements checking what the current value of the name attribute is set to and comparing that to the onValue variable.

When on IS set then that means you are telling toggleAttr "I want you to toggle all elements to true/false and ignore what the current value is". So it doesn't need to loop through all the elements and check what the current value is set to because you told it to brute force the value.

Example: http://jsfiddle.net/petersendidit/sHJC3/2/

PetersenDidIt
I think I see: so when `set` is passed a jQuery object, and that object is a list, `set` implicitly operates on the elements of the list, because `jQuery.fn.removeAttr` and `jQuery.fn.attr` implicitly operate on the elements of the list. Is that correct?
Joe Mabel
correct `jQuery.fn.removeAttr` and `jQuery.fn.attr` run on jQuery objects, doesn't matter if the jQuery object has 12 elements in the collection or 1.
PetersenDidIt