kofifus kofifus - 2 months ago 19
HTML Question

event currentTarget changes after setTimeout

consider:



let sel=document.getElementById('mys');

sel.onchange=function(e) {
console.log(e.currentTarget===null); // false
setTimeout(e => {
console.log(e.currentTarget===null); // true
}, 0, e);
}

<select id="mys">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>






  • why does e.currentTarget changes after the timeout ? is that a browser (chrome) bug ?

  • how can I transfer an exact clone of the event to the timeout function ? I tried simple cloning but currentTarget is not writable and cannot be ovverridden ..


Answer

Passing the arguments with setTimeout seems to be problematic. Use call to call function:

let sel = document.getElementById('mys');

sel.onchange = function(e) {
    console.log(e.currentTarget === null);
    setTimeout(function(evt) {
       console.log(evt.currentTarget === null);
    }.call(undefined, e), 0);
}
<select id="mys">
  <option value="volvo">Volvo</option>
  <option value="saab">Saab</option>
  <option value="mercedes">Mercedes</option>
  <option value="audi">Audi</option>
</select>

The reason why in setTimeout, currentTarget is null is because after the event handler is triggered, then the currentTarget property becomes null. And since you have a timeout, you access currentTarget after the handler is triggered, thus logging null.

With a call or IIFE, you call the function immediately, before the handler has finished triggering, giving you a non-null currentTarget. This means the timeout is completely disregarded.

Comments