首页 > 解决方案 > 我可以在操作之前将元素上的事件恢复为状态吗?

问题描述

对于我当前的项目,我有一个关于事件处理的问题。问题是我必须向元素添加事件侦听器并在给定元素关闭时删除事件。为了模拟我的问题,而不是通过打开和关闭元素使事情变得复杂,我将展示几个按钮来代表在某些情况下应该发生的事情:

//This event listener was added elsewhere in the script, or in another script:
$("#foo").on("click", function() {
  alert("You just clicked on \"Foo\" button."); //<-- Do not remove this with $.off(), this would be the default event.
});

//This would be my own custom code (please do not remove vanilla/plain javascript here for the solution, as that will be the direction I want to be going for my project):
document.querySelectorAll("#add").forEach(node => node.addEventListener("click", function() {
  $("#foo").on("click", function() {
    alert("Another event has been added to \"foo\" button.");
  }); //<-- How to remove only this event (or any newly event added with this button), and not the default event given above?
}));

$("#remove").on("click", function() {
  $("#foo").off(); //<-- Do not remove default event with this, how? Or how to revert to default event?
});

$("#revert").on("click", function() {
  //How could I revert whatever events were assigned to the "#foo" button (before the event(s) were removed by "#remove" button and before it was manipulated by the "#add" button)?
})
<link href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<button id="foo" class="btn btn-default">
  Execute event(s)
</button>

<button id="add" class="btn btn-default">
  Add event(s) to previous button
</button>

<button id="remove" class="btn btn-default">
  Remove event(s)
</button>

<button id="revert" class="btn btn-default">
  Revert back to default event
</button>

JSFiddle

我希望“删除事件”按钮仅删除新添加的事件。或者我想保持它以这种方式工作并让最后一个按钮工作(这样我就可以使用所需的代码将它与函数的删除结合起来,这反过来会导致我正在寻找的相同行为) .

<button id="foo">可以在删除任何事件之前以某种方式“保存”默认事件(在本例中为 jQuery's $.off())吗?我可以为<button id="foo">删除事件破例吗?

标签: javascriptjquery

解决方案


以下是您使用常规 DOM API 会执行的操作:

function defaultListener() {
  console.log("You just clicked on \"Foo\" button.");
}

function additionalListener() {
  console.log("Another event has been added to \"foo\" button.");
}

foo.addEventListener("click", defaultListener);

add.addEventListener("click", function() {
  foo.addEventListener("click", additionalListener);
});

remove.addEventListener("click", function() {
  foo.removeEventListener("click", additionalListener);
});
<link href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<button id="foo" class="btn btn-default">
  Execute event(s)
</button>

<button id="add" class="btn btn-default">
  Add event(s) to previous button
</button>

<button id="remove" class="btn btn-default">
  Remove additonal event
</button>

能够删除事件侦听器的关键是将处理函数的引用传递el.removeEventListener(eventName, handler)(这就是为什么我将代码放在两个命名函数中defaultListener()additionalListener()而不是代码使用的任何匿名函数中)。


推荐阅读