简体   繁体   English

在带有各种侦听器的for循环中使用addEventListener()

[英]Using addEventListener() in a for loop with various listeners

I'm trying to add listeners to a number of buttons using a for loop. 我正在尝试使用for循环将侦听器添加到多个按钮。 The appropriate listener for each button is indicated by the ID attribute of the button. 每个按钮的适当侦听器由该按钮的ID属性指示。 Button IDs follow the form "button-[listenerName]". 按钮ID遵循“ button- [listenerName]”的形式。 I get the list of all my button elements using querySelectorAll() , and then I iterate through that list, slicing out the name of each listener from the name of each button element. 我使用querySelectorAll()获取所有按钮元素的列表,然后遍历该列表,从每个按钮元素的名称中切出每个侦听器的名称。 Then, I use the name of the listener with addEventListener() in an attempt to associate that button with its listener. 然后,我将监听器的名称与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>

Unfortunately, it doesn't work. 不幸的是,它不起作用。 What's up with that? 那是怎么回事? Thank you. 谢谢。

There are 3 issues with your code: 您的代码存在3个问题:

  1. In your for loop, you are essentially attaching strings as eventlisteners. 在for循环中,您实际上是将字符串作为事件侦听器附加。 You need to access your event listeners from the string you have. 您需要从您拥有的字符串访问事件监听器。

Since you eventlisteners are declared in the global scopre, you can use window to access them: 由于您的事件监听器已在全局scopre中声明,因此您可以使用window来访问它们:

button.addEventListener("click", window[listenerName]);
  1. You are attaching the event listeners before declaring them. 您要在声明事件监听器之前附加它们。 You need to declare listener1 and so on before your for loop 您需要在for循环之前声明listener1 ,依此类推

  2. innerHtml does not exist. innerHtml不存在。 The right syntax is innerHTML 正确的语法是innerHTML

Here is a working example: 这是一个工作示例:

<!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>

your line button.addEventListener("click", listenerName); 您的行button.addEventListener("click", listenerName); tried to add a function called listenerName to the click event, and since listenerName is a variable and not a function, it doesn't work. 试图将一个名为listenerName的函数添加到click事件中,并且由于listenerName是变量而不是函数,因此它不起作用。

You could use an array of function to make it work instead. 您可以使用函数数组来使其工作。

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

and then in your loop you could create the listener by giving the right function: 然后在循环中,您可以通过提供正确的函数来创建侦听器:

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

Also, make sure you create the function and the array before running the loop or they won't exist yet when the code runs. 另外,请确保在运行循环之前创建函数和数组,否则在代码运行时它们将不存在。

There's a slightly easier way to do this - just have one function that handles the event: 有一种更简单的方法可以执行此操作-只有一个函数可以处理事件:

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 演示

Or, you can change your loop like this and your code will work 或者,您可以像这样更改循环,代码即可正常工作

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM