Jetz Ki
Jetz Ki

Reputation: 3

jQuery 'each' shorthand

Is there any way I can short hand jquery each? or is there any alternative in writing jquery each which is shorter than the code below?

$('someElement').each(function () {
    functionName('value1', value2)
});
$('anotherElement').each(function () {
    functionName('value1', value2)
});
$('andMoreElement').each(function () {
    functionName('value1', value2)
});

functionName(foo, element){
   //function code here
}

Upvotes: 0

Views: 1949

Answers (4)

T.J. Crowder
T.J. Crowder

Reputation: 1075537

As of the latest version of the question, where all three each use the same values, you're best off either using a comma-series of selectors (if those are selectors), or the add function (if they aren't):

$('someElement, anotherElement, andMoreElement').each(function () {
    functionName('value1', value2)
});

functionName(foo, element){
   //function code here
}

or

$('someElement').add('anotherElement').add('andMoreElement').each(function () {
    functionName('value1', value2)
});

functionName(foo, element){
   //function code here
}

Again, it depends on whether 'someElement', 'anotherElement', and such are selectors or elements.

Because you're using each, which calls the function right away, you can also use the curry option below. If you were using click or similar, using the curry option below would change when value2 was evaluated (from when the function is called to when it's curried), which may be desirable or undesirable depending on your use-case.


Answer for an earlier version of the question:

Sadly, you can't use $.proxy or Function#bind for this, as both of them will change the value of this in the call. You can create a curry function that reuses the this it was called with:

var slice = Array.prototype.slice;
function curry(f) {
    var args = slice.call(arguments, 1); // Copy args after `f`
    return function() {
        return f.apply(this, args.concat(slice.call(arguments, 0)));
    };
}

When you pass a function and X number of arguments into curry, it returns a function that, when called, will call the original function with the this value it was called with, the arguments provided to curry, and then any arguments provided to the call.

Then:

$('someElement').each(curry(functionName, 'foo'));
$('anotherElement').each(curry(functionName, 'otherFoo'));
$('andMoreElement').each(curry(functionName, 'otherFoo'));

functionName(foo){
   //function code here
}

Or as the second two uses have the same argument:

$('someElement').each(curry(functionName, 'foo'));
$('anotherElement, andMoreElement').each(curry(functionName, 'otherFoo'));
// Or:
$('anotherElement').add('andMoreElement').each(curry(functionName, 'otherFoo'));

functionName(foo){
   //function code here
}

Upvotes: 3

Andy
Andy

Reputation: 63589

Edit: this will allow you to pass parameters through as per the edit in your question.

var a = 'Function', b = 'works';

$('.a').each(foo.bind(this, a + 'foo', b + 'foo')); // (1)

function foo(a, b, i, el) {
  console.log(a, b, $(el).text());
}

JSfiddle

(1) I added foo to the vars to prove that foo isn't picking up the globals, but the parameters that are passed in.

Upvotes: 1

Shashank
Shashank

Reputation: 830

 $('#onotherElement','#someElement').each(function () {
        functionName('foo')
    });

Upvotes: 1

Nick Andriopoulos
Nick Andriopoulos

Reputation: 10653

Assuming you want to expand the selection, you might be interested in the .add() function:

$('someElement').add('onotherElement').each(function() { })

will apply your logic to all matches of the someElement as well as onotherElement

Upvotes: 2

Related Questions