Copy a 'change' EventListener function

Viewed 492

I have this HTML tag

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

which has an event listener

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

I would like to copy the function in the listener but all the following lines return null or undefined

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

How can I copy the anonymous function from the listener?

2 Answers

You can't.

You didn't keep a reference to it, and there is no API to pull it out of the list of listeners.

Refactor your code so you keep a reference to it from the start.

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

As an alternative you could trigger the event of the original object with dispatchEvent(). But note, if the function uses this reference it will refer to the original element the event is attached to. Same is true if the event paramter is used (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>

Another alternative is to overwrite the standard addEventListener() function so it will store a reference to the given function. This is an example of this. You probable want to store the reference in a different way but kept it easy as an example.

You only have to make sure that the function is overwritten before the element is created.

//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>

If you want to do this for the window object you probably need to overwrite window.addEventListener because window isn't a Node

Related