0

everyone.

I am trying to manipulate DOM so whenever the user clicks on the categories, I want their background to change to a pinkish color. I tried to add an eventListener to only the first of those categories (whose class is '.select'), and it worked fine. Then I tried to write code for a for loop that can add eventListeners for all of the options, and it didn't work. Also when I run the code for the case in which only the first option gets impacted, its font color is still not changing. How do I fix these issues? Here are my code segments:

<div class="categorybox">
                <ul>
                    <li class="select"><a href="#">Love</a></li>
                    <li class="select"><a href="#">Health</a></li>
                    <li class="select"><a href="#">Beauty</a></li>
                    <li class="select"><a href="#">Gratitude</a></li>
                    <li class="select"><a href="#">Sleep</a></li>
                    <li class="select"><a href="#">Spiritual</a></li>
                    <li class="select"><a href="#">Happiness</a></li>
                    <li class="select"><a href="#">Money</a></li>
                    <li class="select"><a href="#">Blessing</a></li>
                </ul>
</div>
const category = document.querySelector(".select");

category.addEventListener("click", (e) => {
  e.preventDefault();
  category.style.background = "#eb3352";
  category.style.opacity = "0.7";
  category.style.color = "#fcfafa";
});

In the case above, my font color doesn't change to the color I specified (#fcfafa).

Then I tried running the code below.

const categories = document.querySelectorAll(".select");

for (var i = 0; i < categories.length; i++){
  categories[i].addEventListener("click", (e) => {
    e.preventDefault();
    categories[i].style.background = "#eb3352";
    categories[i].style.opacity = "0.7";
    categories[i].style.color = "#fcfafa";
}});

In the case above, none of the selected list items changed.

  • Change `var i` to `let i` and it will work. See the linked question for details. – Barmar Mar 23 '23 at 23:58
  • You can also use `e.target` to get the element that was clicked. – Barmar Mar 23 '23 at 23:59
  • You have syntax error on the end of your script. Change ```}});``` to ```});}``` Inside listener use ```e.currentTarget``` instead ```categories[i]``` – weroro Mar 24 '23 at 00:02

1 Answers1

0

The code you used with document.querySelectorAll does not work for two reasons:

  • Your parentheses and braces are misplaced.
  • You should use let instead of var so that i is scoped to the loop block. With var, i just ends up as categories.length which is the value seen inside the event handler functions.
for (let i = 0; i < categories.length; i++) {
    categories[i].addEventListener("click", (e) => {
        e.preventDefault();
        categories[i].style.background = "#eb3352";
        categories[i].style.opacity = "0.7";
        categories[i].style.color = "#fcfafa";
    });
}

However, consider using event delegation instead. This way, you can just attach the event listener to the parent, then check if the click was on one of the children. event.target can be used to access the element that was clicked.

document.querySelector('.categorybox > ul').addEventListener('click', e => {
  const li = e.target.closest('li.select');
  if (li) {
    e.preventDefault();
    li.style.background = "#eb3352";
    li.style.opacity = "0.7";
    li.style.color = "#fcfafa";
  }
});
<div class="categorybox">
  <ul>
    <li class="select"><a href="#">Love</a></li>
    <li class="select"><a href="#">Health</a></li>
    <li class="select"><a href="#">Beauty</a></li>
    <li class="select"><a href="#">Gratitude</a></li>
    <li class="select"><a href="#">Sleep</a></li>
    <li class="select"><a href="#">Spiritual</a></li>
    <li class="select"><a href="#">Happiness</a></li>
    <li class="select"><a href="#">Money</a></li>
    <li class="select"><a href="#">Blessing</a></li>
  </ul>
</div>
Unmitigated
  • 76,500
  • 11
  • 62
  • 80