Reputation: 1816
Is there an easy way to remove all other classes except the eventarget in with JavaScript.
For example, if I have a UL:
<ul>
<li>list element</li>
<li>list element</li>
<li>list element</li>
<li>list element</li>
<li>list element</li>
<li>list element</li>
</ul>
And I add click event listener with an event handler:
var UL = document.querySelector('ul');
function eventHandler(e) {
var thiz = e.target;
document.querySelectorAll('ul li').classList.remove("active");
thiz.classList.add("active");
}
UL.addEventListener('click', function (e) {
eventHandler(e);
});
How can I add a class on the element being clicked, while removing all the other "active" classes.
Here's a fiddle http://jsfiddle.net/298ZV/
Upvotes: 0
Views: 778
Reputation: 253446
Without jQuery:
[].forEach.call(document.querySelectorAll('ul li'), function(a){
a.classList.remove('active');
});
This uses the Array.prototype.forEach()
to iterate over the NodeList and executes the function on each element.
You could also 'simplify' (though do note the scare-quotes...) a little further and do everything within the same forEach()
:
function eventHandler(e) {
var thiz = e.target;
[].forEach.call(document.querySelectorAll('ul li'), function(a){
a.classList[a == e.target ? 'add' : 'remove']('active');
});
}
With regards to concerns expressd by @adeneo, in comments to his answer, that should the li
elements contain other elements they will become the event.target
I've added a simple closest()
function to find the element you're looking for:
var UL = document.querySelector('ul');
function closest(origin, elem) {
var current = origin;
elem = elem.toLowerCase();
while (current.tagName.toLowerCase() !== 'body' && current.tagName.toLowerCase() !== elem) {
current = current.parentNode;
}
return current;
}
function eventHandler(e) {
var that = closest(e.target, 'li');
[].forEach.call(document.querySelectorAll('ul li'), function(a) {
a.classList[that === a ? 'add' : 'remove']('active');
});
}
UL.addEventListener('click', function (e) {
eventHandler(e);
});
References:
Array.prototype.forEach()
.document.querySelector()
.document.querySelectorAll()
.Element.classList
.Upvotes: 4
Reputation: 318312
Do it a little differently, attach the event handler to the LI's, and keep them in a variable, then iterate over the LI's and remove the class from the ones that aren't this
var LI = document.querySelectorAll('ul li');
for (var i=LI.length; i--;) {
LI[i].addEventListener('click', eventHandler);
}
function eventHandler() {
this.className = 'active';
for (var i=LI.length; i--;) {
if (LI[i] != this) LI[i].className = '';
}
}
Upvotes: 1