use*_*172 75 javascript for-loop addeventlistener
我正在尝试使用for循环向多个对象添加事件侦听器,但最终会将所有侦听器定位到同一个对象 - >最后一个.
如果我通过为每个实例定义boxa和boxb来手动添加侦听器,它就可以工作.我想这就是addEvent for-loop,它不像我希望的那样工作.也许我完全使用了错误的方法.
使用4个class ="container"的示例容器4上的触发器按照预期的方式工作.触发容器1,2,3触发容器4上的事件,但仅在触发器已被激活时触发.
// 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);
}Run Code Online (Sandbox Code Playgroud)
<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>Run Code Online (Sandbox Code Playgroud)
Hal*_*yon 116
瓶盖!: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
}Run Code Online (Sandbox Code Playgroud)
<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>Run Code Online (Sandbox Code Playgroud)
实际上是非严格的JavaScript.它的解释如下:
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);
}
Run Code Online (Sandbox Code Playgroud)
由于变量提升,var声明将移动到范围的顶部.由于JavaScript没有块作用域(for,if,while等),他们无法移动到函数的顶部.更新:从ES6开始,您可以使用let获取块范围变量.
当代码运行时会发生以下情况:在for循环中添加单击回调并分配boxa,但在下一次迭代中它的值会被覆盖.当点击事件触发回调运行和的值boxa是始终在列表的最后一个元素.
使用封闭(封闭的值boxa,boxb等),你绑定值单击处理的范围.
代码分析工具等的JSLint或JSHint将能够赶上可疑这样的代码.如果您正在编写大量代码,那么花些时间学习如何使用这些工具是值得的.有些IDE内置了它们.
ten*_*its 12
您将范围/闭包问题视为function(){makeItHappen(boxa,boxb);} boxa和boxb引用,然后始终是最后一个元素.
要解决这个问题:
function makeItHappenDelegate(a, b) {
return function(){
makeItHappen(a, b)
}
}
// ...
elem[i].addEventListener("click", makeItHappenDelegate(boxa,boxb), false);
Run Code Online (Sandbox Code Playgroud)
你可以使用Function Binding.You不需要使用闭包.见下:
之前:
function addEvents(){
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);
}
}
Run Code Online (Sandbox Code Playgroud)
之后:
function addEvents(){
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", makeItHappen.bind(this, boxa, boxb), false);
elem[k].addEventListener("click", makeItHappen.bind(this, boxa, boxb), false);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
54645 次 |
| 最近记录: |