我试图使用for循环将事件侦听器添加到多个对象,但最终所有侦听器都针对同一对象->最后一个对象。
如果我通过为每个实例定义boxa和boxb手动添加侦听器,则它将起作用。我猜这是addEvent for循环无法按我期望的方式工作。也许我完全使用了错误的方法。
在容器4上使用class =“ container”触发器4的示例按预期方式工作。在容器4上的容器1,2,3触发事件上触发,但仅当触发器已被激活时。
// Function to run on click: function makeItHappen(elem, elem2) { var el = document.getElementById(elem); el.style.backgroundColor = "red"; var el2 = document.getElementById(elem2); el2.style.backgroundColor = "blue"; } // Autoloading function to add the listeners: var elem = document.getElementsByClassName("triggerClass"); for (var i = 0; i < elem.length; i += 2) { var k = i + 1; var boxa = elem[i].parentNode.id; var boxb = elem[k].parentNode.id; elem[i].addEventListener("click", function() { makeItHappen(boxa, boxb); }, false); elem[k].addEventListener("click", function() { makeItHappen(boxb, boxa); }, false); } <div class="container"> <div class="one" id="box1"> <p class="triggerClass">some text</p> </div> <div class="two" id="box2"> <p class="triggerClass">some text</p> </div> </div> <div class="container"> <div class="one" id="box3"> <p class="triggerClass">some text</p> </div> <div class="two" id="box4"> <p class="triggerClass">some text</p> </div> </div>
关闭!:D
此固定代码按预期工作:
// Function to run on click: function makeItHappen(elem, elem2) { var el = document.getElementById(elem); el.style.backgroundColor = "red"; var el2 = document.getElementById(elem2); el2.style.backgroundColor = "blue"; } // Autoloading function to add the listeners: var elem = document.getElementsByClassName("triggerClass"); for (var i = 0; i < elem.length; i += 2) { (function () { var k = i + 1; var boxa = elem[i].parentNode.id; var boxb = elem[k].parentNode.id; elem[i].addEventListener("click", function() { makeItHappen(boxa,boxb); }, false); elem[k].addEventListener("click", function() { makeItHappen(boxb,boxa); }, false); }()); // immediate invocation } <div class="container"> <div class="one" id="box1"> <p class="triggerClass">some text</p> </div> <div class="two" id="box2"> <p class="triggerClass">some text</p> </div> </div> <div class="container"> <div class="one" id="box3"> <p class="triggerClass">some text</p> </div> <div class="two" id="box4"> <p class="triggerClass">some text</p> </div> </div>
for(var i=0; i < elem.length; i+=2){ var k = i + 1; var boxa = elem[i].parentNode.id; var boxb = elem[k].parentNode.id; elem[i].addEventListener("click", function(){makeItHappen(boxa,boxb);}, false); elem[k].addEventListener("click", function(){makeItHappen(boxb,boxa);}, false); }
实际上是非严格的JavaScript。解释如下:
var i, k, boxa, boxb; for(i=0; i < elem.length; i+=2){ k = i + 1; boxa = elem[i].parentNode.id; boxb = elem[k].parentNode.id; elem[i].addEventListener("click", function(){makeItHappen(boxa,boxb);}, false); elem[k].addEventListener("click", function(){makeItHappen(boxb,boxa);}, false); }
由于变量提升,因此var声明将移动到作用域的顶部。由于JavaScript没有块作用域(for,if,while等),他们无法移动到函数的顶部。 更新: 从ES6开始,您可以let用来获取块范围的变量。
var
for
if
while
let
当您的代码运行时,会发生以下情况:在for循环中添加click回调并分配boxa,但是其值在下一次迭代中将被覆盖。当点击事件触发回调运行和的值boxa是始终在列表的最后一个元素。
boxa
使用闭包(关闭的值boxa,boxb等等),将值绑定到点击处理程序的作用域。
boxb