Vanilla Javascript 如何覆盖事件侦听器上添加的功能?

Vanilla Javascript how override added function on event listener?

我有一个bootstrap模态有一些自定义事件,比如hidden.bs.modal,根据用户在哪里,我希望这个事件中的功能被替换,也许更好理解举一个简单的例子,考虑:

const currentModal; // imagine an any modal here.

window.addEventListener('load', () => {
   currentModal.addEventListener('hidden.bs.modal', standardFunction );
});

function standardFunction(){
    alert('hi there');
   // this is standard output to modal closed
}

function buttonClickedChange(){
    // Here, i need override standardFunction

     this.standardFunction = function(){
         alert('modal event hidden.bs.modal changed with success!');
         // this must be override previous output
     };
}

发生的情况是,无论函数是否重新声明,方法的输出仍然是标准的,这是因为事件监听器不引用存储的函数,而只是“复制”其内容并仅创建其作用域里面。

您遇到的问题是,当您绑定事件时,您正在引用该函数。当您替换它时,它不会更新对该函数的引用。您可以清楚地看到这不适用于示例

var btn = document.querySelector("button");
function myFunc () {
  console.log(1);
}

btn.addEventListener("click", myFunc);

myFunc = function() {
  console.log(2);
}
<button>Click Will Show 1</button>

只需删除事件侦听器并绑定一个新事件。

currentModal.removeEventListener('hidden.bs.modal', standardFunction );
currentModal.addEventListener('hidden.bs.modal', myUpdatedFunction );

function myFunc () {
  console.log(1);
}


var btn = document.querySelector("button");
btn.addEventListener("click", myFunc);


function myFunc2() {
  console.log(2);
}

btn.removeEventListener("click", myFunc);
btn.addEventListener("click", myFunc2);
<button>Click</button>

如果由于某种原因您无法删除该事件,唯一的解决办法就是不直接绑定到该函数,而是让另一个函数调用该函数。

var btn = document.querySelector("button");

var myFunc = function() {
  console.log(1);
}

function clickFunction () {
  myFunc();
}

btn.addEventListener("click", clickFunction);

myFunc = function() {
  console.log(2);
}
<button>Click</button>

或者说大多数人会做的是将逻辑添加到函数中以做什么

var btn = document.querySelector("button");
var state = 0;

var myFunc = function() {
  if (state===0) {
    console.log(1);
  } else {
    console.log(2);
  }
}


state = 1;

btn.addEventListener("click", myFunc);
<button>Click</button>

您使用了函数表达式而不是函数声明。当您使用 function yourFunction 时,它会与所有其他声明的函数一起移动到顶部。当你使用 var yourFunction = function () 时,它就在你声明它的地方。这意味着 hidden.bs.modal 正在搜索具有该名称的最顶层函数,在本例中是您声明的第一个函数或标准函数。其中一种方法是您可以在全局范围内声明您的函数:function standardFunctionOverride() 并将其添加到侦听器。