【问题标题】:addEvenListener doesn't work on dynamic button - javascriptaddEventListener 不适用于动态按钮 - javascript
【发布时间】:2015-02-25 15:04:50
【问题描述】:

所以我目前正忙于学习 JavaScript。我创建了一些动态按钮,并尝试向其中添加一个 addEvenListener。但它不起作用,我无法弄清楚为什么它不起作用。我只是在测试一些东西,并尝试使用本地存储中的值创建按钮。它几乎可以工作,只有 addEvenListener 不工作。我只想要一个带有本地存储密钥的简单警报。

for (var i = 0; i <= localStorage.length-1; i++) {
    var categoryButton = document.createElement('input');
    categoryButton.setAttribute('class', 'forumMenu');
    categoryButton.setAttribute('type', 'button');
    categoryButton.setAttribute('name', localStorage.key(i));
    categoryButton.setAttribute('value', localStorage.key(i));
    categoryButton.setAttribute('id', localStorage.key(i));
    categoryButton.addEventListener('click', function(col){
    alert(col);
}(localStorage.key(i)),true);
    forumMenu.appendChild(categoryButton);
}

有谁知道为什么它不起作用?

【问题讨论】:

  • 是不是因为您尝试将事件侦听器添加到按钮之前您将其添加到它们的DOM?
  • 处理函数中的“col”参数是什么?这可能是问题所在。
  • 好吧 col 只是我想出的一个随机名称,但它代表了我想在警报中显示的值
  • somethinghere,我该如何解决?

标签: javascript button addeventlistener


【解决方案1】:

您没有将函数传递给EventTarget.@987654321@。您正在立即执行并传递结果:

function (col) {
  console.log(col);
}(localStorage.key(i))

...这是undefined。您可以使用以下语法对其进行修改:

categoryButton.addEventListener('click', (function(col) { 
   // return a function to addEventListener
   return function(){
      console.log(col);
   }
})(localStorage.key(i)),true);

这是一个演示:

var input;
for (var i = 0; i <= 5; i++) {
  input = document.createElement('input');
  input.type = "button"
  input.value = i;
  input.addEventListener('click', function(i) {
    // return a function to addEventListener
    return function() {
      console.log(i);
    }
  }(i), true);
  document.body.appendChild(input);
}

【讨论】:

  • 这很好用,但我的 html 中有一个特殊的 div 用于按钮。如何将这些按钮添加到该 div?
  • 用适当的元素替换document.body。该演示也不涉及localStorage。它只是作为在循环中添加处理程序的简单示例。
  • 我注意到了,但是当我尝试更改 document.body 时,事件监听器将无法再次工作。我将 document.body 更改为 document.getElementById("forumMenu");
  • @Jari 您的代码表明您已经直接引用了forumMenu。我不能说为什么它不起作用。我提供了一个最小的、功能正常的代码示例。您必须根据自己的需要调整它或提供更多信息。
【解决方案2】:

您将值存储在id 属性中,因此只需使用它:

 for (var i = 0; i <= localStorage.length-1; i++) {
    var categoryButton = document.createElement('input');
    categoryButton.setAttribute('class', 'forumMenu');
    categoryButton.setAttribute('type', 'button');
    categoryButton.setAttribute('name', localStorage.key(i));
    categoryButton.setAttribute('value', localStorage.key(i));
    categoryButton.setAttribute('id', localStorage.key(i));

    categoryButton.addEventListener('click', function () {alert(this.getAttribute('id'));});
 document.body.appendChild(categoryButton);
 }

在事件处理程序中,this 引用了&lt;input&gt; 元素本身,因此您只需检索属性值即可。

【讨论】:

  • 解释您所做的更改以及解决问题的原因/方式。
  • 您当然不必“必须”在 id 中存储数据。而且我认为在 id 中存储任意数据是一种不好的模式。
  • 我不是说你“必须”,只是使用它已经存储的东西。我没有目标,也许存储的id比值好。
  • 哦,对不起,我猜我的脑子里插入了一个“to”。顺便说一句,this.id 将是获取价值的更简单方法。
  • @FelixKling 以及一堆 setAttribute() 调用作为属性公开的值......但这来自 OP 的代码。
【解决方案3】:

那是因为您将该事件侦听器分配给不在 DOM 中的对象(那是因为您在 DOM 加载后创建了此元素)

试试这个:

categoryButton.onclick = function(col){
    alert(col);
}

您可以将函数声明为 var,然后将该函数重新分配给事件处理程序:

var myFunction = function(){
    alert("I'm a function");
}

myElement.onclick = myFunction;

【讨论】:

  • 所以您认为addEventListener 仅在元素在文档中时才有效?为什么?为什么这不适用于onclick
  • 好吧,如果你想“点击”元素,它必须在文档中,不是吗?我发现他试图在页面加载后添加这个元素。
  • 当然,不能在文档中单击该元素之前的元素,但是您可以在引用它后立即绑定一个事件处理程序。但是我仍然很好奇你为什么认为 onclick 会起作用(而 addEventListener 不会)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-18
  • 2021-04-30
  • 2012-11-23
  • 2021-12-14
  • 2019-03-08
  • 2017-07-10
  • 1970-01-01
相关资源
最近更新 更多