从 addEventListener 中提取函数

Extract function from addEventListener

简而言之,我有 3 个 div 会在单击时随机更改其背景颜色。它们只能被点击一次,因此 removeEventListener。我只是想把事情复杂化吗?

我有 3 个事件监听器,它们都使用相同的函数,但每个都有自己的参数:

doorLeft.addEventListener("click", function handler(ev) {
  randomChooseColour(doorLeft);
  ev.currentTarget.removeEventListener(ev.type, handler);
});

doorMiddle.addEventListener("click", function handler(ev) {
  randomChooseColour(doorMiddle);
  ev.currentTarget.removeEventListener(ev.type, handler);
});

doorRight.addEventListener("click", function handler(ev) {
  randomChooseColour(doorRight);
  ev.currentTarget.removeEventListener(ev.type, handler);
});

randomChooseColour 是一个基本函数,它接受一个参数并更改 div 背景颜色

const randomChooseColour = (door) => {
  if (randomSelect(2) === 0) {
    door.style.backgroundColor = winColour;
  } else {
    door.style.backgroundColor = loseColour;
  }
};

有没有办法在 addEventListener 之外创建处理函数?我试图将它保存到一个 const,然后在 eventListener 中使用那个 const,但它似乎不起作用

const choose = function handler(ev, door) {
  randomChooseColour(door);
  ev.currentTarget.removeEventListener(ev.type, handler);
};

然后像这样使用它但是 ev 没有定义.

doorLeft.addEventListener("click", choose(ev, doorLeft));

由于函数体不同,我不认为有一种方法可以调用 removeEventListener 的单个外部函数。但是有一个简单的方法可以简化事情:使用 { once: true } 这样监听器只能被调用一次,根本不需要 removeEventListener

// the below line can be made less repetitive
// by using querySelectorAll instead, if possible
for (const door of [doorLeft, doorMiddle, doorRight]) {
  door.addEventListener(
    'click',
    () => randomChooseColor(door),
    { once: true }
  );
}