简体   繁体   English

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

[英]addEventListener (and removeEventListener) function that need param

I need to add some listeners to 8 object (palms). 我需要向8个对象(手掌)添加一些侦听器。 These object are identical but the behaviour have to change basing to their position. 这些对象是相同的,但是行为必须根据其位置进行更改。 I have the follow (ugly) code: 我有以下(丑陋的)代码:

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); });

I have two needs: 我有两个需求:

1) doesn't use an anonymous function on click event. 1)在点击事件上不使用匿名函数。

I wrote this code, but it doesn't work 我写了这段代码,但是没有用

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

So this one works fine 所以这个很好用

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

But I didn't understand how remove the event listener. 但是我不明白如何删除事件监听器。 I try this solution, but it doesn't work 我尝试了此解决方案,但没有用

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

2) add and remove listener in a for cycle 2)在for周期中添加和删除侦听器

I wrote the follow code but the behaviour is not correct. 我编写了以下代码,但行为不正确。

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

the listeners was added but the value of the parameter passed to the palmShakeHandler is always 8. 添加了侦听器,但传递给palmShakeHandler的参数的值始终为8。

Nobody could help me to fix these issues? 没有人能帮助我解决这些问题吗?

There is a actually, a perfect way to do that in JavaScript using the Function.prototype.bind method. 使用Function.prototype.bind方法,在JavaScript中实际上是一种完美的方法。

bind let you define extra parameters that will be passed, as arguments, of the function. bind使您可以定义额外的参数,这些参数将作为函数的参数传递。

You should also keep in mind that bind creates a new function and doesn't modify the initial function. 您还应该记住, bind会创建一个新函数,并且不会修改初始函数。

Here is what it looks like: 看起来像这样:

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

This should fix your problem, and you will be able to remove handlers easily :) 这应该可以解决您的问题,并且您将能够轻松删除处理程序:)

Your code will look like this: 您的代码将如下所示:

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));
  }
} 

To be able to remove the handler afterward, you need to keep a reference to the function you create with bind . 为了能够在以后删除处理程序,您需要保留对使用bind创建的函数的引用。 This would be the way to do this. 这就是这样做的方法。

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

If you want to know more about the awesome bind method in JavaScript, the MDN is your friend :) https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind 如果您想了解有关JavaScript中很棒的bind方法的更多信息,那么MDN是您的朋友:) https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind

BTW, the problem with you function always returning 8 is a very common question in JavaScript. 顺便说一句,您的函数始终返回8问题是JavaScript中一个非常常见的问题。 This thread will explain everything (spoiler, it's a matter of scoping :) ) https://stackoverflow.com/a/750506/2745879 该线程将解释所有内容(破坏者,这是范围界定的问题:)) https://stackoverflow.com/a/750506/2745879

In your last solution you are pasing the same var to every function and that is what make al the functions work with 8 because is the last value of the variable. 在您的最后一个解决方案中,您要向每个函数粘贴相同的var,这就是使函数与8一起使用的原因,因为它是变量的最后一个值。

To work arround that you can use "let" ( please at least use var, otherside that "i" is global and can be changed every where in the code) but since I dont know wich browser you target I propose other solution. 为了工作,您可以使用“ let”(至少请使用var,否则“ i”是全局的,并且可以在代码中的每个位置更改),但是由于我不知道您所针对的浏览器,因此我建议使用其他解决方案。

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

Since its look like You are targeting modern browsers I will use let. 由于它看起来像您正在针对现代浏览器,因此我将使用let。 https://kangax.github.io/compat-table/es6/ https://kangax.github.io/compat-table/es6/

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

So now you just need to call "removeHandShake" and will remove the listener, 因此,现在您只需要调用“ removeHandShake”即可删除监听器,

I have code this right here so it ease some minor errors to pop 我在这里有此代码,因此可以缓解一些小错误

So in case your array of »palms« is very huge, it is basically a bad Idea to add a single event listener to each of them, because that causes performance flaws. 因此,如果您的»palm«数组非常庞大,则向其中的每个事件添加单个事件侦听器基本上是一个糟糕的主意,因为这会导致性能缺陷。 So I would suggest a different approach: 因此,我建议采用另一种方法:

var handlers = [function (e) {}, …, function (e) {}];

root.game.palms.forEach(functiion (palm, idx) {
  palm.setAttribute('data-idx', idx);
});

<palmsparent>.addEventListener('click', function (e) {
  var c = e.target, idx = -1;

  while (c) {
    if (c.hasAttribute && c.hasAttribute('data-idx')) {
      idx = parseInt(c.getAttribute('data-idx'));
      break;
    }
    c = c.parentNode;
  }

  //here you also check for the »palm status«
  if (idx >= 0) {
    handlers[idx](c);
  }
})

One event listener for all, much easier to remove and better for performance. 所有人都可以使用一个事件侦听器,更容易删除并且可以提高性能。

暂无
暂无

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

相关问题 带有部分功能的Javascript addEventListener和removeEventListener - Javascript addEventListener and removeEventListener with partial function 如何使用匿名函数删除作为addEventListener的EventListener? - How to removeEventListener that is addEventListener with anonymous function? removeEventListener 不工作(函数不是匿名的,和 addEventListener 完全一样!!) - removeEventListener is not working (function is not anonymous, exactly the same as addEventListener!!) 使用addEventListener javascript添加后,removeEventListener()不会删除函数 - removeEventListener() not removing function after added with addEventListener javascript 如何为可与 removeEventListener 一起使用的 addEventListener 创建包装函数? - How can I create a wrapper function for addEventListener that works with removeEventListener? 如何在JavaScript中的方法中的addEventListener和全局函数中的removeEventListener时调用removeEventLisener - How to call removeEventLisener when addEventListener in a method and removeEventListener in a global function in JavaScript 为什么 useEffect() 中的 addEventListener 和 removeEventListener 需要箭头 function? - Why does addEventListener and removeEventListener inside useEffect() require an arrow function? addEventListener 和 removeEventListener 使用 forEach - addEventListener and removeEventListener using forEach Javascript:addEventListener(),removeEventListener()和bind() - Javascript: addEventListener(), removeEventListener() and bind() 如何使用removeEventListener禁用addEventListener? - How to use removeEventListener to disable addEventListener?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM