javascript - 需要参数的addEventListener(和removeEventListener)函数

标签 javascript addeventlistener createjs

我需要向 8 个对象(手掌)添加一些监听器。 这些对象是相同的,但行为必须根据它们的位置而改变。 我有以下(丑陋的)代码:

root.palmsStatus = ["B","B","B","B","B","B","B","B"];

if (root.palmsStatus[0] !== "N")
  root.game.palms.palm1.addEventListener("click", palmHandler = function(){ palmShakeHandler(1); });
if (root.palmsStatus[1] !== "N")
  root.game.palms.palm2.addEventListener("click", palmHandler = function(){ palmShakeHandler(2); });
if (root.palmsStatus[2] !== "N")
  root.game.palms.palm3.addEventListener("click", function(){ palmShakeHandler(3); });
if (root.palmsStatus[3] !== "N")
  root.game.palms.palm4.addEventListener("click", function(){ palmShakeHandler(4); });
if (root.palmsStatus[4] !== "N")
  root.game.palms.palm5.addEventListener("click", function(){ palmShakeHandler(5); });
if (root.palmsStatus[5] !== "N")
  root.game.palms.palm6.addEventListener("click", function(){ palmShakeHandler(6); });
if (root.palmsStatus[6] !== "N")
  root.game.palms.palm7.addEventListener("click", function(){ palmShakeHandler(7); });
if (root.palmsStatus[7] !== "N")
  root.game.palms.palm8.addEventListener("click", function(){ palmShakeHandler(8); });

我有两个需求:

1) 在点击事件上不使用匿名函数。

我写了这段代码,但它不起作用

root.game.palms.palm8.addEventListener("click", palmShakeHandler(8));

所以这个效果很好

root.game.palms.palm8.addEventListener("click", function(){ palmShakeHandler(8); });

但我不明白如何删除事件监听器。 我尝试了这个解决方案,但它不起作用

root.game.palms.palm8.addEventListener("click", palmHandler = function(){ palmShakeHandler(8); });
root.game.palms.palm8.removeEventListener("click", palmHandler);

2)在for循环中添加和删除监听器

我编写了以下代码,但行为不正确。

  for (i=1; i <= root.palmsStatus.length; i++){
    if (root.palmsStatus[i-1] !== "N"){
      root.game.palms["palm" + i].addEventListener("click", function(){ palmShakeHandler(i); });
    }
  } 

监听器已添加,但传递给 palmShakeHandler 的参数值始终为 8。

没有人能帮我解决这些问题吗?

最佳答案

实际上,有一种完美的方法可以在 JavaScript 中使用 Function.prototype.bind 方法来实现这一点。

bind 允许您定义将作为函数参数传递的额外参数。

您还应该记住,bind 创建一个新函数并且不会修改初始函数。

它是这样的:

function palmHandler(number) {
  // your code working with `number`
}

var palmHandler8 = palmHandler.bind(null, 8)
// the palmHandler8 is now tied to the value 8.
// the first argument (here null) define what `this` is bound to in this function

这应该可以解决您的问题,并且您将能够轻松删除处理程序:)

您的代码将如下所示:

for (i=1; i <= root.palmsStatus.length; i++){
  if (root.palmsStatus[i-1] !== "N"){
    root.game.palms["palm" + i].addEventListener("click", palmShakeHandler.bind(null, i));
  }
} 

为了能够在之后删除处理程序,您需要保留对使用 bind 创建的函数的引用。这就是做到这一点的方法。

var boundHandler = handler.bind(null, i);
element.addEventListener(boundHandler);
element.removeEventListener(bounderHander);

如果您想了解有关 JavaScript 中令人敬畏的 bind 方法的更多信息,MDN 是您的 friend :) https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind

顺便说一句,函数总是返回 8 的问题是 JavaScript 中一个非常常见的问题。该线程将解释一切(剧透,这是范围界定的问题:))https://stackoverflow.com/a/750506/2745879

关于javascript - 需要参数的addEventListener(和removeEventListener)函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44257208/

相关文章:

html - 同一 HTML 页面中的两个 Flash cc 动画

javascript - CreateJS - 为什么在创建 createjs 位图时仅使用路径适用于 Firefox 而不适用于 Chrome

javascript - 在每张打印纸中重复内容

javascript - 如何在 Jquery UI 小部件中实现继承

Javascript removeEventListener 不工作

javascript - 如何将 addEventListener 与所有 HTML 按钮、复选框、单选、选择和 href 一起使用

javascript - Javascript 无限循环会阻止渲染吗?

javascript - 编辑 Vue 数据时出现问题

JavaScript,迭代类并单击显示隐藏的 tr

javascript - 访问类函数?