Javascript 通过for循环添加事件侦听器
我对一些JavaScript代码有一些问题。 我试图做的是向数组中的元素添加事件侦听器 问题是,在运行代码后,只有数组中的最后一个元素使eventlistener工作,其余元素返回错误 我假设这是因为我在for循环和eventlisteners中使用的逻辑。 实现预期结果的有效方法是什么Javascript 通过for循环添加事件侦听器,javascript,Javascript,我对一些JavaScript代码有一些问题。 我试图做的是向数组中的元素添加事件侦听器 问题是,在运行代码后,只有数组中的最后一个元素使eventlistener工作,其余元素返回错误 我假设这是因为我在for循环和eventlisteners中使用的逻辑。 实现预期结果的有效方法是什么 function addSlider(config) { var controls = ` <div id="next"> next </div> <
function addSlider(config) {
var controls = `
<div id="next"> next </div>
<div id="previous"> previous </div>`;
var S_wrapper = config.wrapper;
var controls_html = document.createElement("div");
controls_html.setAttribute("id", "ctrl");
controls_html.innerHTML = controls;
var arrayData = config.wrapper.split(",");
for (i = 0; i < arrayData.length; i++) {
(function(index) {
document.querySelector(arrayData[i]).appendChild(controls_html);
var parent = document.querySelector(arrayData[index]);
console.log(i, index, arrayData[index], parent);
document.querySelector(arrayData[index]).addEventListener("mouseover", function(){
this.querySelector("#ctrl").style.display = "block";
})
document.querySelector(arrayData[index]).addEventListener("mouseout", function(){
this.querySelector("#ctrl").style.display = "none";
})
})(i);
}
}PS:我将回答您当前代码中的问题,而不是讨论其他人已经对此发表评论的设计/重构 您的主要问题是使用id而不是类。请记住,文档中只能存在一个id,否则无法引用它们 此外,如果您也在重用controls_html元素,则应该为要添加到的每个元素创建一个新的控件。同样,在这种情况下 我已经创建了一个包含您代码的工作副本的 函数addSliderconfig{ 变量控制=` 下一个 以前的`; var S_wrapper=config.wrapper; var arrayData=config.wrapper.split,; 对于i=0;i
document.querySelector(arrayData[i]).appendChild(controls_html);
将其从最初没有的父级移动,但在第一个循环之后,它是从上一个循环到新父级的元素
如果要在每个父级中创建一个新的div,则每次都需要创建一个新div
您在多个元素上使用了相同的ID ctrl。这是无效的,ID必须是唯一的。稍后,当您使用ctrl键时,您将得到浏览器选择给您的任何元素,这都是未指定的行为,尽管根据我的经验,它总是第一个
因此,我们需要处理这两个问题。对您的方法解决方案进行最小的更改,我们将div创建移动到循环中,并将索引添加到ID中:
function addSlider(config) {
var controls = `
<div id="next"> next </div>
<div id="previous"> previous </div>`;
var S_wrapper = config.wrapper;
var arrayData = config.wrapper.split(",");
for (i = 0; i < arrayData.length; i++) {
(function(index) {
var div = document.createElement("div");
div.setAttribute("id", "ctrl" + index);
div.innerHTML = controls;
var parent = document.querySelector(arrayData[index]);
parent.appendChild(div);
parent.addEventListener("mouseover", function() {
this.querySelector("#ctrl" + index).style.display = "block";
})
parent.addEventListener("mouseout", function() {
this.querySelector("#ctrl" + index).style.display = "none";
})
})(i);
}
}
但我会退后一步,看看更广阔的前景。例如,mouseover和mouseout都会冒泡,因此您可以将它们挂接到父元素上,并使用单个处理程序处理。也可能根本没有理由使用这个ID;我们可以识别具有类或类似类的子div,并且只在父类中搜索它。可以用ArrayforEach替换循环及其内的函数。诸如此类的事情
旁注:我注意到您正在使用一个模板文字来指定控件,这是ES2015又称ES6中引入的一个功能,但没有使用任何其他ES2015功能。如果您没有意识到…您是否考虑过将事件侦听器添加到所有渲染arrayData的父节点,以便每个元素只需要一个处理程序,而不是相同的处理程序?但是是的,你的问题是一个与关闭相关的问题,我会设法找到重复的。