【问题标题】:Using addEventListener() in a for loop with various listeners在具有各种侦听器的 for 循环中使用 addEventListener()
【发布时间】:2017-12-08 02:05:18
【问题描述】:

我正在尝试使用 for 循环将侦听器添加到多个按钮。每个按钮的相应侦听器由按钮的 ID 属性指示。按钮 ID 遵循“button-[listenerName]”的形式。我使用querySelectorAll() 获取所有按钮元素的列表,然后遍历该列表,从每个按钮元素的名称中切出每个侦听器的名称。然后,我将侦听器的名称与addEventListener() 一起使用,以尝试将该按钮与其侦听器相关联。

<!DOCTYPE html>
<html>
<body>

<button id="button-listener1">Try 1</button>
<button id="button-listener2">Try 2</button>
<button id="button-listener3">Try 3</button>
<button id="button-listener4">Try 4</button>

<p id="demo"></p>

<script>

var selector = "[id^=button]";
var allButtons = document.querySelectorAll(selector);
for (var button of allButtons) {
  var listenerName = button.id.slice(button.id.lastIndexOf("-")+1);
  button.addEventListener("click", listenerName);
}

var listener1 = function() {
  document.getElementById('demo').innerHtml = "1";
}

var listener2 = function() {
  document.getElementById('demo').innerHtml = "2";
}

var listener3 = function() {
  document.getElementById('demo').innerHtml = "3";
}

var listener4 = function() {
  document.getElementById('demo').innerHtml = "4";
}

</script>

</body>
</html>

不幸的是,它不起作用。那是怎么回事?谢谢。

【问题讨论】:

  • 您的控制台显示什么错误?
  • 寻求调试帮助的问题(“为什么这段代码不起作用?”)必须包括所需的行为、特定的问题或错误以及在问题本身中重现它所需的最短代码。没有明确问题陈述的问题对其他读者没有用处。请参阅:如何创建最小、完整和可验证的示例。
  • 您需要通过添加无效内容的详细信息来完成您的问题。
  • 好吧..你不是在添加一个监听函数,而是一个字符串..这是怎么回事
  • 为什么不将它们附加到同一个事件监听器。当一个按钮被点击时,你可以使用this.id 来知道哪个按钮被点击了。

标签: javascript for-loop addeventlistener


【解决方案1】:

您的代码存在 3 个问题:

  1. 在您的 for 循环中,您实际上是在附加字符串作为事件监听器。您需要从您拥有的字符串中访问您的事件侦听器。

由于您的事件监听器是在全局范围中声明的,您可以使用window 来访问它们:

button.addEventListener("click", window[listenerName]);
  1. 您在声明事件侦听器之前附加它们。你需要在你的for循环之前声明listener1等等

  2. innerHtml 不存在。正确的语法是innerHTML

这是一个工作示例:

<!DOCTYPE html>
<html>
<body>

<button id="button-listener1">Try 1</button>
<button id="button-listener2">Try 2</button>
<button id="button-listener3">Try 3</button>
<button id="button-listener4">Try 4</button>

<p id="demo"></p>

<script>

var listener1 = function() {
  document.getElementById('demo').innerHTML = "1";
}


var listener2 = function() {
  document.getElementById('demo').innerHTML = "2";
}

var listener3 = function() {
  document.getElementById('demo').innerHTML = "3";
}

var listener4 = function() {
  document.getElementById('demo').innerHTML = "4";
}

var selector = "[id^=button]";
var allButtons = document.querySelectorAll(selector);
for (var button of allButtons) {
  var listenerName = button.id.slice(button.id.lastIndexOf("-")+1);
  button.addEventListener("click", window[listenerName]);
}
</script>

</body>
</html>

【讨论】:

  • 赞成这个答案不是因为它是最优雅或最有效的解决方案,而是因为它从提问者的角度来处理问题并同情提问者的困惑
  • 谢谢,这正是我所需要的。
【解决方案2】:

您的button.addEventListener("click", listenerName); 行尝试在点击事件中添加一个名为 listenerName 的函数,由于 listenerName 是一个变量而不是函数,所以它不起作用。

你可以使用一个函数数组来代替它。

var array_of_functions = [
    'listener1' : listener1,
    'listener2' : listener2,
    'listener3' : listener3,
    'listener4' : listener4
]

然后在您的循环中,您可以通过提供正确的函数来创建侦听器:

button.addEventListener("click", array_of_functions[listenerName]);

另外,请确保在运行循环之前创建函数和数组,否则在代码运行时它们将不存在。

【讨论】:

    【解决方案3】:

    有一种更简单的方法可以做到这一点 - 只需 一个 处理事件的函数:

    for (var button of allButtons) {
      button.addEventListener("click", handleClick, false);
    }
    
    function handleClick() {
      var id = this.id.match(/button-listener(\d)/)[1];
      document.getElementById('demo').innerHTML = id;
    }
    

    DEMO

    【讨论】:

      【解决方案4】:

      或者,你可以像这样改变你的循环,你的代码就可以工作了

      allButtons.forEach(function (button, i) {
          var listenerName = button.id.slice(button.id.lastIndexOf("-") + 1);
          button.addEventListener("click", function () {
          document.getElementById('demo').innerHTML = i + 1;
        });
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-09
        • 1970-01-01
        • 1970-01-01
        • 2016-03-29
        • 2021-12-03
        • 1970-01-01
        相关资源
        最近更新 更多