События массивов объектов


#1
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
    .color {
        height: 200px;
        width: 200px;
        background: #0d0da2;
        margin: 5px;    
    }
    #test {
        height: 200px;
        width: 200px;
        background: #0d0da2;
        margin: 5px;    
    }   
</style>
</head>
<body>
<div class="color"></div>
<div class="color"></div>
<div id="test"></div>
<script>
    var color = document.getElementsByClassName("color");
    var color1 = color[0];
    color1.onclick = function  () {
        color1.style.background = (color1.style.background == "green") ? "#0d0da2" : "green";
    }
    for (var i = 0; i < color.length; i++) {
        color[i].onclick = function () {
        color[i].style.background = (color[i].style.background == "green") ? "#0d0da2" : "green";
    }
}
    var test = document.getElementById("test");
    test.onclick = function  () {
        test.style.background = (test.style.background == "green") ? "#0d0da2" : "green";
    }
</script>
</body>
</html>

вот хочу попробовать подключить событие к каждому элементу массива. в коде присутствуют три варианта: событие элемента массива, событие элементов массива, и событие объекта (тут все просто, все работает). первые два варианта не работают. буду благодарен, если подскажете почему


#2

все, разобрался. просто в событии поменял названия эл-тов на this.


#3
for (var i = 0; i < color.length; i++) {
	color[i].onclick = function() {
		color[i].style.background = (color[i].style.background == "green") ? "#0d0da2" : "green";
	}
}

Это классическая проблема. Дело в том чему равно значение i в момент вызова функции обработчика. Получается цикл закончил свое выполнение, в теле создал анонимных функций, которые используют одну и ту же i. А по окончанию цикла значение i стало индексом последнего элемента.

Задача решается “замыканием” - созданием области видимости, в которой i именно такая же, какой была в момент итерации цикла. Создаю, вызываю анонимную функцию, передаю i аргументом и принимаю. Теперь функция-обработчик работает с значением i, которая была в момент вызова

for (var i = 0; i < color.length; i++) {
	(function (i) {
		color[i].onclick = function() {
			color[i].style.background = (color[i].style.background == "green") ? "#0d0da2" : "green";
		}
	}(i));
}

#4

спасибо за объяснение и за код!