Why does is x and y immutable in JavaScript running in an <IMG> event handler?

42 Views Asked by At

I'm Using Chrome in case this is a browser-specific behaviour

When I try to set the value of the x variable using JavaScript in an image's onLoad or onError event handler I'm not able to. x and y seem to be set to the coordinates of the image and when I try to change them the value is not updated and no errors are logged in the JS console.

Example: https://jsfiddle.net/brth8zxy/

Code in that page:

<img src="https://media1.tenor.com/m/557GUrcXp14AAAAC/jinx-cat-javascript.gif" onLoad="alert(`x=${x}...\nNow setting x=100`);x=100;alert(`x=${x}\nWell that didn't work... Why?`)">

Interestingly this behaviour isn't present if I call a function in the onLoad event handler. Maybe something to do with scope?

1

There are 1 best solutions below

3
mandy8055 On BEST ANSWER

The behavior that you're mentioning is indeed related to the scope. Let me share my insights on this in the context of your example.

So, when you use x directly in the onLoad attribute, it refers to the x property of the global window object. In the context of an event handler, the global window object is not the same as the scope in which the event handler is executed1. Event handlers run in the context of the element that triggered the event2.

Now, in your example the onLoad event handler is executed in the context of the <img> element. Since the <img> element does not have an x property, the event handler looks up the prototype chain and finds the x property on the window object. This is why the value of x does not change when you try to set it to 100.

So, what will happen if you use a function in the onLoad event handler, as you have mentioned?

  <!-- The answer is you create a new scope for the x variable, 
which allows you to set and update its value as expected.-->

<script>
  function handleImageLoad() {
    let x = 0;
    alert(`x=${x}...\nNow setting x=100`);
    x = 100;
    alert(`x=${x}\nNow it works!`);
  }
</script>

<img src="https://media1.tenor.com/m/557GUrcXp14AAAAC/jinx-cat-javascript.gif" onLoad="handleImageLoad()">


References:

  1. Last paragraph on How scope works
  2. Event and Dom Nodes
  3. Why the subtle cross browser differences in event object?