Adil Heybetov
Adil Heybetov

Reputation: 23

How to remove active class from all li elements except one that clicked?

It doesn't let me to complete slider in my mind. And I also want to note that not use JQuery. Only with JavaScript. I tried many ways, but it didn't take effect.

var ul = document.querySelector('ul');
var dots = [];

for (var i = 0; i < 5; i++) {
  var dot = document.createElement('li');
  dots.push(dot);
  ul.appendChild(dot);
}
dots[2].setAttribute('class', 'active');
li {
  width: 20px;
  height: 20px;
  background-color: lightgrey;
  text-decoration: none;
  display: inline-block;
  border-radius: 100%;
  margin-right: 15px;
}

.active {
  background-color: grey;
}
<ul></ul>

Here is JSFiddle link: https://jsfiddle.net/heybetov1998/camuyve2/4/

Upvotes: 1

Views: 8524

Answers (3)

H77
H77

Reputation: 5967

Use addEventListener to assign a listener to the click event of the li element you're adding.

Within the listener function you can remove the active class for all li elements and then add it only to the one clicked using this to refer to it.

Use the classList property of the element to add/remove the active class from the element.

var ul = document.querySelector('ul');
var dots = [];

function dotClicked() {
  dots.forEach(function(li) {
    li.classList.remove("active");
  });
  this.classList.add("active");
}

for (var i = 0; i < 5; i++) {
  var dot = document.createElement('li');
  dot.addEventListener("click", dotClicked);
  dots.push(dot);
  ul.appendChild(dot);
}
li {
  width: 20px;
  height: 20px;
  background-color: lightgrey;
  text-decoration: none;
  display: inline-block;
  border-radius: 100%;
  margin-right: 15px;
}

.active {
  background-color: grey;
}
<ul></ul>

Upvotes: 0

spanky
spanky

Reputation: 2880

Here's an event handler that will do it for you.

function handler(event) {
  for (const li of document.querySelectorAll("li.active")) {
    li.classList.remove("active");
  }
  event.currentTarget.classList.add("active");
}

I'll leave it to you to set up the event handler and figure out about legacy browser support if you wish.

Upvotes: 6

T.J. Crowder
T.J. Crowder

Reputation: 1075705

You can hook up an event handler on the dots. Within the event handler, this will refer to the element on which you attached the handler. Then you can remove the class from all the others:

var ul = document.querySelector('ul');
var dots = [];

for (var i = 0; i < 5; i++) {
  var dot = document.createElement('li');
  dot.addEventListener("click", clickHandler); // ** Hook up the handler
  dots.push(dot);
  ul.appendChild(dot);
}
dots[2].setAttribute('class', 'active');

// Here's the handler
function clickHandler() {
  var dots = document.querySelectorAll("li");
  for (var n = 0; n < dots.length; ++n) {
    if (dots[n] !== this) {
      dots[n].className = "";
    }
  }
  this.className = "active";
}
li {
  width: 20px;
  height: 20px;
  background-color: lightgrey;
  text-decoration: none;
  display: inline-block;
  border-radius: 100%;
  margin-right: 15px;
}

.active {
  background-color: grey;
}
<ul></ul>

If you need to support obsolete browsers that don't have addEventListener, this answer has a function for doing that.

That's the minimal-changes version. But there are several changes I'd look at making:

  • Don't use setAttribute to set the class attribute. It fails on very old versions of IE, but more importantly, it completely replaces the classes on the element. Look at classList.

  • The example above hooks up an event handler to each dot, but if you have a lot of dots, or you add/remove them dynamically, you might be better off using event delegation by hooking up the handler on the container of the dots and then using e.target to determine which dot was clicked.

Upvotes: 1

Related Questions