Reputation: 51
I try to toggle class when td
clicked in multiple class but it does not work. I prefer working on DOM.
window.onload = function() {
var seats = document.getElementsByClassName('seat');
for(var i = 0; i < seats.length; i++) {
seats[i].onclick = function() {
seats[i].classList.toggle = 'selected';
}
}
}
td {
width: 30px;
height: 30px;
background-color: red;
color: white;}
td.selected {
background-color: black;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<table>
<tr>
<td class="seat">1</td>
<td class="seat">2</td>
<td class="seat">3</td>
<td class="seat">4</td>
<td class="seat">5</td>
</tr>
</table>
</body>
</html>
http://jsbin.com/kufemuhagi/edit?html,css,js,output
Upvotes: 3
Views: 101
Reputation: 67505
Problem :
You've a scope problem in the posted code where your variable i
counldn't found inside the event handler, this variable is accessible just outside of it, to fix this you need to wrap the assignment of the event listener in a closure, like :
for (var i = 0; i < seats.length; i++) {
(function(i) {
seats[i].onclick = function() {
seats[i].classList.toggle('selected');
}
})(i);
}
window.onload = function() {
var seats = document.getElementsByClassName('seat');
for (var i = 0; i < seats.length; i++) {
(function(i) {
seats[i].onclick = function() {
console.log(i);
seats[i].classList.toggle('selected');
}
})(i);
}
}
td {
width: 30px;
height: 30px;
background-color: red;
color: white;
}
td.selected {
background-color: black;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<table>
<tr>
<td class="seat">1</td>
<td class="seat">2</td>
<td class="seat">3</td>
<td class="seat">4</td>
<td class="seat">5</td>
</tr>
</table>
</body>
</html>
My suggestion :
Separate you logic and use addEventListener()
to attach the events, then use this
to toggle your class, like the sample below shows.
window.onload = function() {
var seats = document.getElementsByClassName('seat');
var clickHandler = function() {
this.classList.toggle('selected');
};
for (var i = 0; i < seats.length; i++) {
seats[i].addEventListener('click', clickHandler, false);
}
}
div.selected {
background-color: green;
}
<div class="seat">Div 1</div>
<div class="seat">Div 2</div>
<div class="seat">Div 3</div>
<div class="seat">Div 4</div>
Upvotes: 3
Reputation: 334
The Problem with your code is that the variable i
isn't defined per iteration it is defined in the function scope. That means that the for
loop you have goes trough every element and assigns the onclick
handler to each "seat" but after the last iteration the i
variable will be set to an out-of-bounds index since the for
loop does the i++
expression after each iteration. The problem is your onclick
handler refers to the i
variable, which is set to an out-of-bounds index, so that the seats[i]
expression returns an undefined
value. You can fix this by using the this
statement inside the onclick
handler or by using the first argument which is the click event. The click event contains a target
which refers to the clicked EventTarget
(this should be your "seat" element).
function handleSeatClick(ev) {
var seat = ev.target;
if(seat.classList.contains('selected')){
seat.classList.remove('selected');
} else {
seat.classList.add('selected');
}
}
window.onload = function() {
var seats = document.getElementsByClassName('seat');
for(var i = 0; i < seats.length; i++) {
seats[i].addEventListener('click', handleSeatClick);
}
}
td {
width: 30px;
height: 30px;
background-color: red;
color: white;}
td.selected {
background-color: black;}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<table>
<tr>
<td class="seat">1</td>
<td class="seat">2</td>
<td class="seat">3</td>
<td class="seat">4</td>
<td class="seat">5</td>
</tr>
</table>
</body>
</html>
Upvotes: 0
Reputation: 6830
Hope this will help.
window.onload = function() {
var seats = document.getElementsByClassName('seat');
for(var i = 0; i < seats.length; i++) {
seats[i].onclick = function() {
this.classList.toggle('selected'); //this will refer current object here and toggle is function
}
}
}
td {
width: 30px;
height: 30px;
background-color: red;
color: white;}
td.selected {
background-color: black;}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<table>
<tr>
<td class="seat">1</td>
<td class="seat">2</td>
<td class="seat">3</td>
<td class="seat">4</td>
<td class="seat">5</td>
</tr>
</table>
</body>
</html>
Upvotes: -1