Favour Oghenekowho
Favour Oghenekowho

Reputation: 5

Adding a CSS property to an HTML

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

Answers (3)

Koala
Koala

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

Abdullah Qasemi
Abdullah Qasemi

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

RickN
RickN

Reputation: 13500

You're almost there. There is a small problem here:

  1. The user clicks on an item.
  2. All items get their CSS class removed.
  3. The clicked item gets a CSS class added if it doesn't already exist.

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

Related Questions