Reputation: 177
When I apply the same function to several elements, I usually do the following:
var func = function(elem) {
elem.style.color = 'red';
};
var p = document.querySelector('p');
var div = document.querySelector('div');
func(p);
func(div);
I was wondering if there is an easy way to apply this function to two (or more) elements at once ? Eg :
func(p, div); // Apply my function to both elements at once
Upvotes: 1
Views: 385
Reputation: 3816
You could combine some of the great answers here to come up with a functionnal programming code easily reusable :
var f = function (applyTo) {
var makeArray = function(arrayLike) {
return Array.prototype.slice.call(arrayLike);
};
return function () {
var args = makeArray(arguments),
elements = [];
args.forEach(function (selector) {
var newElements = makeArray(document.querySelectorAll(selector));
console.log(newElements);
elements = elements.concat(newElements);
});
elements.forEach(applyTo);
}
};
var redify = function (elem) {
elem.style.color = '#F00';
}
var underline = function (elem) {
elem.style.textDecoration = 'underline';
}
var overline = function (elem) {
elem.style.textDecoration = 'overline';
}
f(redify)('div', 'p');
f(underline)('div.test2');
f(overline)('p.test2');
Upvotes: 1
Reputation:
By transforming the function so it returns itself, you can use the syntax
func(p)(div)
To make this work, you'll need to arrange for func
to return itself.
function selfify(fn) {
return function self() {
fn.apply(this, arguments);
return self;
};
}
Then
funcx = selfify(func);
funcx(p)(div);
If you would prefer the func(p, div)
syntax, write the following kind of transformer, which creates a function which calls an underlying function on each of its arguments:
function repeatify(fn) {
return function() {
Array.prototype.forEach.call(arguments, fn, this);
};
}
Then
funcy = repeatify(func);
funcy(p, div);
This obviously won't work well if the underlying function takes two or more parameters.
In ES6, using rest parameters, the above can be written somewhat more simply as
function repeatify(fn) {
return function(...args) {
[...args].forEach(fn, this);
};
}
If all the above functional-style programming is too much to wrap your head around, all you really need to do is:
[p, div].forEach(func);
Upvotes: 2
Reputation: 1
Consider combining a basic loop from the previous answers and the use of classes instead of querySelector.
Thus you could assign the needed classed to all your element that you'll need to pass through the function and then just call the function with them:
var func = function (elem) {
for (var i = 0; i < elem.length; i++) {
elem[i].style.color = 'red';
}
};
func(document.getElementsByClassName("yourClass"));
Upvotes: 0
Reputation: 37825
var forEach = Array.prototype.forEach;
var elms = document.querySelectorAll('p, div'); // css selector to match both p & div
var func = function(elem) {
elem.style.color = 'red';
};
forEach.call(elms, func);
Upvotes: 0
Reputation: 668
You can make use of arguments
:
var func = function() {
var args = [].slice.apply(arguments);
args.forEach(function (elem) {
elem.style.color = 'red';
});
};
Call it like you wanted:
func(p, div);
On a side note, there is a functionality called "rest parameter" planned in ECMAScript 6 that allows for just what you had in mind, take a look here.
Upvotes: 4
Reputation: 2573
The right way to do is through the use of classes.
<p class="myClass"></p>
<div class="myClass"></div>
Then in your javascript when you wish to change the color of these two elements, simply do:
var elems = document.getElementsByClassName("myClass");
for(var i=0; i<elems.length; i++){
func(elem[i]);
}
It'll be useful for long run when you have large number of elements, organizing them in classes based on your needs is the way to go.
Upvotes: -1