首页 > 解决方案 > 动态创建的元素 EventListener 上的对象修改问题

问题描述

在使用 Vanilla Javascript 对动态创建的元素使用事件侦听器时,我遇到了一个非常有趣的问题。我将首先定义问题,然后发布代码。

我使用 javascript 创建动态 html 元素,并在创建过程中在每个新创建的对象上添加“单击”事件侦听器。在此事件事件侦听器中,我更改了 GLOBAL 对象的不同属性。我的意思是,当您单击动态创建的元素时,每个元素都会修改此全局对象的不同属性。

这里出现问题,我动态选择全局对象的不同属性。因此,对于每个元素,它都会修改全局对象的不同属性。但是当我运行代码时,我看到每个元素只更改全局对象的最新属性。这意味着每个元素都会更改该对象的相同属性,并且它是该对象的最新属性。这里的代码:

var filter = {1:false, 4:false, 7:false, 11:false, 8:false} //global object
var productsAndIndexes = {a:1, b:4, c:7, d:11, e:8 } //another global object used for looping 
function createEmptyFilter(){
  var hdr = document.querySelector("div.content .headers");
  for(var product in productsAndIndexes){
    var inp = document.createElement("input");
    inp.setAttribute("type", "checkbox");
    var filterInd = productsAndIndexes[product];

    inp.addEventListener("click" , (e) => {
      if(e.target.checked){
        filters[ filterInd ] = true;
      }else{
        filters[ filterInd ] = false;
      }
    });

    hdr.appendChild(inp);
  }
}
createEmptyFilter();

每次我选中一个复选框时,都会得到 filter = {1:false, 4:false, 7:false, 11:false, 8:true}。但相反,每个复选框都应该修改其在对象中的相关部分。

感谢您对问题的任何解释和解决方案(尽管我不是 15 代表 :))谢谢

标签: javascript

解决方案


问题是您的filterInd变量被声明为var意味着它是函数作用域,而不是作用域到您的 for 循环块。这意味着每次循环迭代都会覆盖同一个变量,因此点击处理程序都关闭同一个变量,而不是具有不同值的唯一变量。const用or声明它,let处理click程序将引用循环迭代唯一的值。

由于您使用的浏览器足够现代以支持=>,那么您可能支持letand const; 现在真的没有充分的理由使用var

const filter = {1:false, 4:false, 7:false, 11:false, 8:false} //global object
const productsAndIndexes = {a:1, b:4, c:7, d:11, e:8 } //another global object used for looping 
function createEmptyFilter(){
  const hdr = document.querySelector("div.content .headers");
  for (let product in productsAndIndexes) {
    const inp = document.createElement("input");
    inp.setAttribute("type", "checkbox");
    const filterInd = productsAndIndexes[product];

    inp.addEventListener("click", e => {
      if (e.target.checked) {
        filters[filterInd] = true;
      } else {
        filters[filterInd] = false;
      }
    });

    hdr.appendChild(inp);
  }
}
createEmptyFilter();

推荐阅读