javascript - 如何为数组(或节点列表)进行事件委托(delegate)

标签 javascript for-loop parameters event-delegation

我一生中第一次尝试使用事件委托(delegate)/switch 语句,但在 for 循环方面遇到了麻烦。当它是“array[i]”时,这不是问题。但现在我正在删除 for 循环以使用事件委托(delegate)并将其放入函数内部,它不断给我错误,而且我不知道什么参数可以替换(并使代码再次工作)该 array[i ] 在新函数中。任何帮助或解释将不胜感激。

//original code

const numbers = document.querySelectorAll(".number");

for (let i = 0; i < numbers.length; i++) {
  numbers[i].addEventListener("click", function () {
    if (display.value.length < 13) {
      return;
    }
    if (display.value == "0" && numbers[i] != dot) {
      display.value = numbers[i].innerText;
      calculation = display.value;
    } else {
      if (numbers[i] == dot && display.value.includes(".")) {
        return;
      } else if (numbers[i] == dot && display.value == "") {
        return;
      } else {
        display.value += numbers[i].innerText;
        calculation = display.value;
      }
    }

    buttonEffect(numbers[i], "number-active");
  });
}
// New code

const numbers = document.querySelectorAll(".number");

function numberClick(number) {
  if (display.value.length > 13) {
    return;
  }
  if (display.value == "0" && this != dot) {
    display.value = number.innerText;
    calculation = display.value;
  } else {
    if (numbers == dot && display.value.includes(".")) {
      return;
    } else if (number == dot && display.value == "") {
      return;
    } else {
      display.value += number.innerText;
      calculation = display.value;
    }
  }
  operatorOnOff = false;
  buttonEffect(number, "number-active");
}




document.querySelector(".wrapper").addEventListener("click", (e) => {
  switch (e.target.dataset.key) {
    case "number":
      numberClick();
      break;
}
});

最佳答案

您将作为点击目标的元素传递到 numberClick 中,并在之前使用 numbers[i] 的位置使用它。看起来您已经在执行第二部分了,甚至还为其声明了一个参数,您只需传入该元素即可:

numberClick(e.target);

请注意,如果您的 .number 元素具有子元素,则 target 可能是这些子元素之一,而不是 .number。为了解决这个问题,您可以使用 DOM 相对较新的 closest方法,可能与 contains 结合使用,以确保它与 .wrapper 周围的内容不匹配:

document.querySelector(".wrapper").addEventListener("click", (e) => {
    const number = e.target.closest(".number");
    if (number && this.contains(number) && number.dataset.key) {
        numberClick(number);
    }
});

如果您需要支持过时的浏览器,可以使用polyfills,或者自己做循环:

document.querySelector(".wrapper").addEventListener("click", (e) => {
    let number = e.target;
    while (number && !number.matches(".number")) {
        if (this === number) {
            return; // Reached the wrapper without finding it
        }
        number = number.parentElement;
    }
    if (number && number.dataset.key) {
        numberClick(number);
    }
});

关于javascript - 如何为数组(或节点列表)进行事件委托(delegate),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62695658/

相关文章:

javascript - JS 表单验证问题

javascript - 将 for() 循环中的所有分号替换为 @ 符号

C# While 循环与 For 循环?

javascript - 如何修改内联函数参数?

c++ - "local variables at the outermost scope of the function may not use the same name as any parameter"是什么意思?

javascript - 类/原型(prototype)继承后获取当前 'class name'

javascript - var myvalue = window.opener.document.getElementById (“parentId1” ) 不工作

javascript - Dojo - xhrPut 中变量赋值发生得太晚

for-loop - 如何根据当前页面变量显示来自 Jekyll 数据文件的数据

ruby-on-rails - Rails 中带有哈希值的不允许的参数