I'm trying to figure out a way to be able to add a class to the target element, whilst at the same time remove a class from another element with the same class.
I have this code so far. The code works as desired, however it is saying the object is undefined and I am confused as to why that would be. Is there a better way to do what I am trying to do?
It must be in pure vanilla javascript. thanks in advance HTML
<ul class="number-container"><li class="number-item"><span class="number number-active" data-number="zero"></span></li>
<li class="number-item"><span class="number" data-number="one">1</span></li>
<li class="number-item"><span class="number" data-number="two">2</span></li>
<li class="number-item"><span class="number" data-number="three">3</span></li>
<li class="number-item"><span class="number" data-number="four">4</span></li>
<li class="number-item"><span class="number" data-number="five">5</span></li>
<li class="number-item"><span class="number" data-number="six">6</span></li>
<li class="number-item"><span class="number" data-number="seven">7</span></li>
<li class="number-item"><span class="number" data-number="eight">8</span></li>
<li class="number-item"><span class="number" data-number="nine"></span></li>
</ul>
Javascript
// store elements in dom
var numberButtons = document.querySelectorAll(".number");
// loop to add event listener to each button
for (var i = 0; i < numberButtons.length; i++) {
// add click event listener
numberButtons[i].addEventListener("click", changeButton);
}
function changeButton(e) {
// get dataset value
var target = e.target;
var targetDataset = e.currentTarget.dataset.number;
for (var i = 0; i <= numberButtons.length; i++) {
numberButtons[i].classList.remove("number-active");
if (targetDataset === "zero") {
target.classList.add("number-active");
} else if (targetDataset === "one") {
target.classList.add("number-active");
} else if (targetDataset === "two") {
target.classList.add("number-active");
} else if (targetDataset === "three") {
target.classList.add("number-active");
} else if (targetDataset === "four") {
target.classList.add("number-active");
} else if (targetDataset === "five") {
target.classList.add("number-active");
} else if (targetDataset === "six") {
target.classList.add("number-active");
} else if (targetDataset === "seven") {
target.classList.add("number-active");
} else if (targetDataset === "eight") {
target.classList.add("number-active");
} else if (targetDataset === "nine") {
target.classList.add("number-active");
}
}
}
I'm trying to figure out a way to be able to add a class to the target element, whilst at the same time remove a class from another element with the same class.
I have this code so far. The code works as desired, however it is saying the object is undefined and I am confused as to why that would be. Is there a better way to do what I am trying to do?
It must be in pure vanilla javascript. thanks in advance HTML
<ul class="number-container"><li class="number-item"><span class="number number-active" data-number="zero"></span></li>
<li class="number-item"><span class="number" data-number="one">1</span></li>
<li class="number-item"><span class="number" data-number="two">2</span></li>
<li class="number-item"><span class="number" data-number="three">3</span></li>
<li class="number-item"><span class="number" data-number="four">4</span></li>
<li class="number-item"><span class="number" data-number="five">5</span></li>
<li class="number-item"><span class="number" data-number="six">6</span></li>
<li class="number-item"><span class="number" data-number="seven">7</span></li>
<li class="number-item"><span class="number" data-number="eight">8</span></li>
<li class="number-item"><span class="number" data-number="nine"></span></li>
</ul>
Javascript
// store elements in dom
var numberButtons = document.querySelectorAll(".number");
// loop to add event listener to each button
for (var i = 0; i < numberButtons.length; i++) {
// add click event listener
numberButtons[i].addEventListener("click", changeButton);
}
function changeButton(e) {
// get dataset value
var target = e.target;
var targetDataset = e.currentTarget.dataset.number;
for (var i = 0; i <= numberButtons.length; i++) {
numberButtons[i].classList.remove("number-active");
if (targetDataset === "zero") {
target.classList.add("number-active");
} else if (targetDataset === "one") {
target.classList.add("number-active");
} else if (targetDataset === "two") {
target.classList.add("number-active");
} else if (targetDataset === "three") {
target.classList.add("number-active");
} else if (targetDataset === "four") {
target.classList.add("number-active");
} else if (targetDataset === "five") {
target.classList.add("number-active");
} else if (targetDataset === "six") {
target.classList.add("number-active");
} else if (targetDataset === "seven") {
target.classList.add("number-active");
} else if (targetDataset === "eight") {
target.classList.add("number-active");
} else if (targetDataset === "nine") {
target.classList.add("number-active");
}
}
}
Share
Improve this question
asked Jul 14, 2017 at 22:12
norrisollienorrisollie
3311 gold badge6 silver badges18 bronze badges
2 Answers
Reset to default 4EDIT: Your initial mistake is the line for (var i = 0; i <= numberButtons.length; i++) {
, you need a <
, not a <=
.
What do you need the data-number
attribute for? In target
you already have your selected element.
Your script can be simplified:
var numberButtons = document.getElementsByClassName("number");
for (var i = 0; i < numberButtons.length; i++) {
numberButtons[i].addEventListener("click", changeButton);
}
function changeButton(e) {
var oldActive = document.getElementsByClassName("number-active");
// depending on your usage you could also replace oldActive by numberButtons
for (var i = 0; i < oldActive.length; i++) {
oldActive[i].classList.remove("number-active");
}
e.target.classList.add("number-active");
}
I uploaded a sample to Codepen.
An efficient way is to use JavaScript to keep some previous state. One step further, the following code hide the state by using closure.
function selector(token) {
var last;
return function(element) {
if (element !== last) {
if (last) last.classList.remove(token);
element.classList.add(token);
last = element;
}
}
}
var select = selector('number-active');
document.querySelector('ul').addEventListener('click', function(e) {
var target = e.target;
if (target.classList.contains('number')) {
select(target);
}
});
https://jsfiddle/7qdqxzrs/
The undefined
error es from the condition check in for
statement. ES6 has for..of
, which can make things easier.
for (var numberButton of numberButtons) {...}