复制一个 'change' EventListener 函数

Copy a 'change' EventListener function

我有这个 HTML 标签

<input type="file" id="File">

它有一个事件侦听器

document.getElementById("File").addEventListener("change", function() {alert("test")});

我想复制侦听器中的函数,但以下所有行 return null 或 undefined

document.getElementById("File").getAttribute("change")
//null
document.getElementById("File").change
//undefined
document.getElementById("File").getAttribute("onchange")
//null
document.getElementById("File").onchange
//null

如何从侦听器复制匿名函数?

你不能。

您没有保留对它的引用,也没有API将它从收听者列表中拉出。

重构您的代码,以便从一开始就保留对它的引用。

function myChangeHandler (event) {
    alert("test");
}
document.getElementById("File").addEventListener("change", myChangeHandler);

作为替代方案,您可以使用 dispatchEvent() 触发原始对象的事件。但请注意,如果函数使用 this 引用,它将引用事件附加到的原始元素。如果使用 event 参数(function(event){})也是如此。

document.getElementById("test").addEventListener("change", function() {
  console.log("test");
  console.log("triggered element id: " + this.id);
});

document.getElementById("manual").addEventListener("click", function() {
  document.getElementById("test").dispatchEvent(new Event('change'));
});
<input id="test">
<button id="manual">manual</button>

另一种替代方法是覆盖标准 addEventListener() 函数,这样它将存储对给定函数的引用。这是一个例子。您可能想以不同的方式存储参考,但作为示例保持简单。

您只需确保在创建元素之前覆盖该函数。

//Store the orignal addEventListener() function under a new name so we can still use it.
Node.prototype.originalAddEventListener = Node.prototype.addEventListener;
//Create a variable where we store the handler for the #test1 element
var test1Handler;

//overwrite the orignal function with our own so it will store a reference to the #test1 event handler in the variable
Node.prototype.addEventListener = function(e, fn){
  if(this.id === 'test1') {
    test1Handler = fn;
  }
  this.originalAddEventListener(e, fn);
}

//Attach event with the overwritten function, lets say this is done by an extarnal libary.
document.getElementById('test1').addEventListener('change', function(){
  console.log("Changing element id: " + this.id);
});

//When the button is clicked the change handler of test1 is copied to test2.
document.getElementById('exec').addEventListener('click', function(){
  document.getElementById('test2').addEventListener('change', test1Handler);
});
<label for="test1">Test 1</label><input id="test1"><br>
<button id="exec">Add Test 1 change handler to Test 2</button><br>
<label for="test2">Test 2</label><input id="test2"><br>

如果您想为 window 对象执行此操作,您可能需要覆盖 window.addEventListener,因为 window 不是 Node