1

Assuming the function doSomething() is defined in the same place, does the function's scope when it is executed differ between these three methods of listening for events?

<body onload="doSomething();">
document.body.onload = doSomething;
document.body.addEventListener('load', doSomething);

Aside from attributes only being able to contain one "listener" compared to addEventListener(), are there any other differences between listening for events in these three ways? (such as passed in parameters, or the value of this?)

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
IQAndreas
  • 8,060
  • 8
  • 39
  • 74
  • Well, in the attribute code you're obviously neither passing a `this` value nor the event to `doSomething()` … – Bergi Apr 11 '14 at 01:26
  • 1
    While not relevant to your question, the third one wont do anything. You need to bind to the `'load'` event, rather than `'onload'` – enhzflep Apr 11 '14 at 01:31
  • 1
    @enhzflep Oops, that was a typo. Thanks, fixed. – IQAndreas Apr 11 '14 at 01:31
  • @enhzflep Though, difficult to debug typos like that wouldn't arise if JavaScript were stronly typed like AS3. My "fix": https://twitter.com/IQAndreas/status/453754209582583808 – IQAndreas Apr 11 '14 at 04:54
  • @IQAndreas - I personally, wouldn't consider that an improvement. You still have to remember that the 'on' prefix doesn't apply when using addEventListener. While it is true that you get the benefit of having a bunch of handler names in a block, which may aid in identifying a single errant one, it's an awful lot more typing (read: code-bloat) for something that consequently runs ever so slightly more slowly. That said - it's an approach that wouldn't suit me, since I can remember them (or lookup the names very quickly). Other's mileage would obviously vary. – enhzflep Apr 11 '14 at 05:23

1 Answers1

3

onload="doSomething();" is similar to

document.body.onload = function(event) { 
    doSomething();
};

Inside the event handler itself, this refers to the element the handler is bound to, but inside doSomething, this will refer to window, since you are calling the function "normally". doSomething doesn't have access to the event object either. You have to pass this and event along if you want doSomething work the same as in the other cases:

onload="doSomething.call(this, event);"

Note: Properties of document, ancestor DOM elements and the DOM element itself are in the scope for the event handler (not doSomething), which can lead to very confusing behavior. See my answer here for more info.

document.body.onload = doSomething; and document.body.addEventListener('load', doSomething); are equivalent in terms of scope and context, and they don't have this strange scope behavior that inline event handlers have.

More information about the different ways can be found on quirksmode.org.

Community
  • 1
  • 1
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • Just being pedantic here. After some testing, there seems to be one slight difference to what you called _"similar to"_. It seems like when placed in the `body.onload` variable, the callback function is stored as a named function (as opposed to your anonymous function). See: http://jsfiddle.net/IQAndreas/ytW6B/1/ – IQAndreas Apr 11 '14 at 04:44
  • Shouldn't affect the scope though, I just included that point for perfection's sake. – IQAndreas Apr 11 '14 at 04:49