我有这个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
如何从侦听器复制匿名函数?
答案 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