Reputation: 5
I'm trying to listen for a click event on a node list to add a CSS property, I don't want two nodes to have the property and I also want to toggle the CSS property on any of the node list with a second click, I can't seem to get the right guard clause to use, any Help.
enter code here
const action = document.querySelectorAll ('.item');
const clearColor = function() {
action.forEach(function(item) {
item.classList.remove('item-color');
})
}
action.forEach(function(item) {
item.addEventListener("click", function(e) {
const target = e.target;
clearColor();
target.classList.toggle("item-color")
})
})
.hidden {
display: none;
}
.item {
margin: 10px;
}
.item-color {
background-color: red;
}
<div class="action">
<div class="item">pizza</div>
<div class="item">rice</div>
<div class="item">spaghetti</div>
<div class="item">honey</div>
<div class="item">cheese</div>
</div>
**strong text**
Upvotes: 0
Views: 68
Reputation: 1
Try something like this.
const action = document.querySelectorAll('.item');
action.forEach(function(item) {
item.addEventListener('click', (e) => {
item.classList.toggle('item-color');
for(let i = 0; i < action.length; i++){
if(e.currentTarget != action[i]){
action[i].classList.remove('item-color');
}
}
});
})
.hidden {
display: none;
}
.item {
margin: 10px;
}
.item-color {
background-color: red;
}
<div class="action">
<div class="item">pizza</div>
<div class="item">rice</div>
<div class="item">spaghetti</div>
<div class="item">honey</div>
<div class="item">cheese</div>
</div>
Upvotes: 0
Reputation: 459
This is the solution I came up with. Not the best but gets the job done.
const action = document.querySelectorAll ('.item');
const clearColor = function() {
action.forEach(function(item) {
item.classList.remove('item-color');
})
}
action.forEach(function(item) {
item.addEventListener("click", function(e) {
const target = e.target;
if(target.classList.contains("item-color")){
clearColor();
}else{
clearColor();
target.classList.toggle("item-color")
}
})
})
.hidden {
display: none;
}
.item {
margin: 10px;
}
.item-color {
background-color: red;
}
<div class="action">
<div class="item">pizza</div>
<div class="item">rice</div>
<div class="item">spaghetti</div>
<div class="item">honey</div>
<div class="item">cheese</div>
</div>
Upvotes: 1
Reputation: 13500
You're almost there. There is a small problem here:
The subtle thing here is that "if it doesn't already exists" is always true for the clicked item, because you just removed its CSS class in step 2.
The solution is to not remove the class in step 2:
const clearColor = function(except) {
action.forEach(function(item) {
if (item === except) {
return;
}
item.classList.remove('item-color');
})
}
// ...
clearColor(target);
By filtering out the clicked element from the items you're removing the CSS classes from, .toggle()
will work as expected.
Upvotes: 2