Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript events: window.event vs argument reference (function)

What is the difference between:

function test (e) {
    console.log("Event: ", e);
}
document.querySelector("button").onclick = test;
<button>Click!</button>

and:

function test () {
    console.log("Event: ", event); // same as window.event
}
document.querySelector("button").onclick = test;
<button>Click!</button>

They seem to return the exact same object, even containing the same timeStamp value in milliseconds.

I often see code using the first example, using e or evt, but what is wrong with the second example?

I understand that event is the same as window.event, which is a global variable, but what is the purpose of using e if event does the same thing?

like image 470
bryc Avatar asked Mar 17 '23 13:03

bryc


1 Answers

Standard ways

There are two standard ways to add event listeners: event handlers and addEventListener.

Event handlers

Initially DOM0 (not defined by any spec but widely implemented), they are properly defined in the HTML5 spec.

Many objects can have event handlers specified. These act as non-capture event listeners for the object on which they are specified. [DOM]

An event handler has a name, which always starts with "on" and is followed by the name of the event for which it is intended.

An event handler can either have the value null, or be set to a callback object, or be set to an internal raw uncompiled handler. The EventHandler callback function type describes how this is exposed to scripts. Initially, event handlers must be set to null.

Event handlers are exposed in one of two ways.

The first way, common to all event handlers, is as an event handler IDL attribute.

The second way is as an event handler content attribute.

Event handler IDL attributes

An event handler IDL attribute is an IDL attribute for a specific event handler. The name of the IDL attribute is the same as the name of the event handler.

The event handler will be the function assigned to the IDL attribute. That function (or callback) will be called with the event as its only argument:

Invoke callback with one argument, the value of which is the Event object E

Example:

document.querySelector("button").onclick = function(evt) {
  console.log('Event: ' + evt);
};
<button>Click!</button>

Event handler content attributes

An event handler content attribute is a content attribute for a specific event handler. The name of the content attribute is the same as the name of the event handler.

When you set them, the handler will be an internal raw uncompiled handler. That means that getting the current value of the event handler will be more complex: the string will be parsed as the FunctionBody of a function which has an argument named event:

Let the function have a single argument called event.

Examples:

<button onclick="console.log('Event: ' + event);">Click!</button>

document.querySelector("button").setAttribute('onclick',
  "console.log('Event: ' + event);"
);
<button>Click!</button>

addEventListener

It was introduced by DOM L2 Events, and now DOM4 defines it as:

The addEventListener(type, callback, capture) method must run these steps:

  1. If callback is null, terminate these steps.

  2. Append an event listener to the associated list of event listeners with type set to type, callback set to callback, and capture set to capture, unless there already is an event listener in that list with the same type, callback, and capture.

When the event listeners are invoked, the callback is called with the event as its only argument:

Call listener's callback's handleEvent, with the event passed to this algorithm as the first argument

Example:

document.querySelector("button").addEventListener('click', function(evt) {
  console.log('Event: ' + evt);
});
<button>Click!</button>

Compatibility notes

Old IE didn't support addEventListener, and didn't pass any argument to event handlers.

However, it provided another way to access the event: window objects inherit an event property from Window.prototype. That property has a getter which returns the event object.

Therefore, a common way to support old IE is using an argument and overriding it with window.event if necessary:

document.querySelector("button").onclick = function(evt) {
  evt = evt || window.event;
  console.log('Event: ' + evt);
};
<button>Click!</button>

New IE passes the event as an argument in both addEventListener and event handlers, so that is no longer necessary. It also continues implementing Window.prototype.event.

Similarly, Chrome implements window.event, probably to support old code written for IE.

However, better avoid using that:

  • It is not standard.
  • The standard alternatives are widely implemented (except on old IE).
  • It doesn't work on all browsers, for example on Firefox.
like image 91
Oriol Avatar answered Mar 25 '23 11:03

Oriol