Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/91.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在循环中单击另一个时向元素添加事件侦听器_Javascript_Html_Dom_Addeventlistener - Fatal编程技术网

Javascript 在循环中单击另一个时向元素添加事件侦听器

Javascript 在循环中单击另一个时向元素添加事件侦听器,javascript,html,dom,addeventlistener,Javascript,Html,Dom,Addeventlistener,我的打字脚本项目有一个很烦人的问题。没什么好想象的,但出于某种原因,一旦我单击这3个菜单中的任何一个元素,onclick的执行次数与特定菜单中的元素数量相同,而不是每次单击一次 我已经尝试了一段时间,因此在注释或不同的添加侦听器中,函数略有不同 如何在菜单中选择一个选项,使这些EventListener只执行一次 onst menu1 = document.getElementById("menu1") as HTMLDivElement; const menu2 = doc

我的打字脚本项目有一个很烦人的问题。没什么好想象的,但出于某种原因,一旦我单击这3个菜单中的任何一个元素,onclick的执行次数与特定菜单中的元素数量相同,而不是每次单击一次

我已经尝试了一段时间,因此在注释或不同的添加侦听器中,函数略有不同

如何在菜单中选择一个选项,使这些EventListener只执行一次

onst menu1 = document.getElementById("menu1") as HTMLDivElement;
const menu2 = document.getElementById("menu2") as HTMLDivElement;
const menu3 = document.getElementById("menu3") as HTMLDivElement;



menu1.addEventListener("click",  function () {

  let elements = menu1.querySelectorAll("input");
  for(let i=0; i< elements.length; i++) {
      elements[i].addEventListener("click", function () {
        if (elements[i].checked) {
          let val = elements[i].value;
          dataSet.setEffect(elements[i].value);
          console.log(dataSet);
        }
      });
    }
});


menu2.addEventListener("click", function(){

  const elements2 = menu1.querySelectorAll("label");
  // for (let element of elements2) {
  //   element.addEventListener("click", function () {
  //       dataSet.setEffect(element.value);
  //       console.log(dataSet);
  //   });
  // }
  elements2.forEach( function (ele,index) {
      // ele.addEventListener("click", function () {
      //         dataSet.setEffect(ele.innerText);
      //         console.log(dataSet);
      // });
  ele.onclick = function () {
    dataSet.setEffect(ele.innerText);
    console.log(dataSet,ele);
  }
  })

});


menu3.addEventListener("click", ()=>{
  let elements3 = menu3.children;
  for(let i=0; i< elements3.length; i++)
  {
    elements3[i].addEventListener("click", ()=>{
      dataSet.setBGC(elements3[i].id);
      console.log(dataSet);
    });
  }
});
onst menu1=document.getElementById(“menu1”)作为htmldevelment;
const menu2=document.getElementById(“menu2”)作为HTMLVelment;
const menu3=document.getElementById(“menu3”)作为HTMLVelment;
菜单1.addEventListener(“单击”),函数(){
让elements=menu1.querySelectorAll(“输入”);
for(设i=0;i{
让elements3=menu3.children;
for(设i=0;i{
setBGC(elements3[i].id);
console.log(数据集);
});
}
});
用于单个菜单的html

 <div class="container">
        <div class="header-text">
            <h2>Effect</h2>
        </div>
        <div class="select" id="menu1" tabindex="1">
            <input class="options-select"  value="solidColor" name="selectors1" type="radio" id="opt1" checked>
                <label for="opt1" class="option">Solid Color</label>
            <input class="options-select" value="EQCenter" name="selectors1" type="radio" id="opt2">
                <label for="opt2" class="option">EQ Center</label>
            <input class="options-select" value="Strobe" name="selectors1" type="radio" id="opt3">
                <label for="opt3" class="option">Strobe</label>
            <input class="options-select" value="Sparkel" name="selectors1" type="radio" id="opt4">
                <label for="opt4" class="option">Sparkel</label>
            <input class="options-select" value="swicth" name="selectors1" type="radio" id="opt5">
                <label for="opt5" class="option">Switch</label>
        </div>
        
    </div>


影响
纯色
情商中心
选通
斯帕克尔
转换

问题在于事件(也称为“冒泡”,如链接的MDN文章中所述)。每次单击一个
输入时,它也会触发每个父元素上的事件。由于这包括菜单本身,因此该菜单的事件处理程序将再次运行—为每个项目添加更多事件侦听器

解决此问题的最简单代码更改是使用事件对象的内置
stopPropagation
方法来防止此问题:

  elements[i].addEventListener("click", function (event) {
    event.stopPropagation();
    if (elements[i].checked) {
      let val = elements[i].value;
      dataSet.setEffect(elements[i].value);
      console.log(dataSet);
    }
  });
然而,虽然这应该可以解决问题,但我强烈建议您思考实现目标的不同方法。在另一个事件监听器中添加一个事件监听器基本上是一种反模式——它很容易导致像您在这里遇到的问题,我正在努力思考任何需要或有用的情况。因为您的输入就在HTML源代码中,而不是用Javascript动态添加,所以我看不出为什么您不能在加载页面时直接将事件侦听器添加到每个输入中。这将导致代码更干净、更简单。

您写道:

每次单击
menu1
,然后将新的onClick侦听器附加到其每个子项

menu1.addEventListener("click",  function () {
  let elements = menu1.querySelectorAll("input");
  for(let i=0; i< elements.length; i++) {
      elements[i].addEventListener("click", function () {
        if (elements[i].checked) {
          let val = elements[i].value;
          dataSet.setEffect(elements[i].value);
          console.log(dataSet);
        }
      });
    }
});
menu1.addEventListener(“单击”),函数(){
让elements=menu1.querySelectorAll(“输入”);
for(设i=0;i
换成

let elements = menu1.querySelectorAll("input");
for(let i=0; i< elements.length; i++) {
  let elem = elements[i]; //To avoid the common closure problem
  elem.addEventListener("click", function () {
    if (elem.checked) {
      let val = elem.value;
      dataSet.setEffect(elem.value);
      console.log(dataSet);
    }
   });
}
let elements=menu1.querySelectorAll(“输入”);
for(设i=0;i
addEventListener追加,因此每次单击时都会将另一个侦听器追加到列表中。