复制一个'change'EventListener函数

时间:2019-01-04 10:34:52

标签: javascript onchange addeventlistener

我有这个HTML标记

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

具有事件监听器

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

我想在侦听器中复制该函数,但以下所有行均返回null或未定义

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

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

2 个答案:

答案 0 :(得分:3)

你不能。

您没有保留对它的引用,也没有API可以将其从侦听器列表中拉出。

重构代码,以便从一开始就对其进行引用。

template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;

// ...

template <typename Visitor> struct Applicator {
  static typename Visitor::State apply(typename Visitor::State s, Event e) {
    return std::visit(overloaded{
      [&s](auto e) mutable -> decltype(Visitor::apply(s, e)) { return Visitor::apply(s, e); },
      [&s](auto) { return s; }
    }, e);
  }
};

答案 1 :(得分:1)

作为替代方案,您可以使用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.addEventListener,因为窗口不是Node