Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery: apply function to elements at the same time

With jQuery.each(), I can iterate through members of the array:

// This is NOT what I am looking for.
$('.example a').each(function() {
    // do a lot of things here
    $(this).css('color', 'red');
});


However, I need to apply a function to the jQuery array itself, and not to its members. So I wrote a little plugin to do this:

$.fn.all = function( callback ) { return callback.call( this ); }

$('.example a').all(function() {
    // do a lot of things here
    $(this).css('color', 'red');
});


Please notice that in the function above, this will be set to the collection of the elements - which is what I require.
Now I'm sure that jQuery should have an elegant way to do this, but I haven't found anything in the documentation, or by Googling.

Is it possible, and if it is, how do I achieve this without using custom plugins?

UPDATE: I can not do $('.example a').css('color', 'red'); directly. I have a dozens of calculations in the function, so I have to use something similar to the plugin I wrote. I am asking for a callback. The correct answer must provide a callback similar to the custom function.

like image 422
David Refoua Avatar asked May 06 '16 20:05

David Refoua


3 Answers

You don't need a plugin, you can use call directly:

(function() {
  // do a lot of things here
  this.css('color', 'red');
}).call($('.example a'));

Or consider passing the array-like object as an argument

(function(arrayLike) {
  // do a lot of things here
  arrayLike.css('color', 'red');
})($('.example a'));

Or if you prefer a jQuery way

$.each([$('.example a')], function(){
  // do a lot of things here
  this.css('color', 'red');
});
like image 168
Oriol Avatar answered Oct 06 '22 09:10

Oriol


Shouldn't

$('.example a').css('color', 'red');

be enough?

like image 40
Patrick Gregorio Avatar answered Oct 06 '22 09:10

Patrick Gregorio


That would be the straight-forward (jQuery-esque) way to do what you want:

var $collection = $('.example a');
$collection.each(function() {
    // do a lot of things here
    $collection.css('color', 'red');
});

//And another reason I dislike jQuery's implementation of each().
//but most of all, wrong argument-order and the abuse of this to pass the current value/node

Here my prefered implementation. Mostly like Array.prototype.forEach(), and the nice parts of $.each().

$.fn.forEach = function(fn, scope){
    if(scope != null) fn = fn.bind(scope);
    for(var i = 0, len = this.length; i < len; ++i)
        if(false === fn(this[i], i, this)) break;
    return this;
}

and your code would be like:

$('.example a').forEach(function(node, index, $collection){
    //and don't use `$(this)`, since `this` most of the time references `window`
    //unless you've bound the function to a scope, or passed one to forEach

    var $node = $(node);

    $collection.css('color', 'red');
});
like image 31
Thomas Avatar answered Oct 06 '22 08:10

Thomas