Skip to content

Instantly share code, notes, and snippets.

@esfand
Last active August 29, 2015 13:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save esfand/10111140 to your computer and use it in GitHub Desktop.
Save esfand/10111140 to your computer and use it in GitHub Desktop.
DOM Event Handling Models

DOM Level 0

This event handling model was introduced by Netscape Navigator, and remains the most cross-browser model as of 2005. There are two model types: inline model and traditional model.

Inline model

In the inline model, event handlers are added as attributes of elements. In the example below, an alert dialog box with the message "Hey Joe" appears after the hyperlink is clicked. The default click action is cancelled by returning false in the event handler.

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Inline Event Handling</title>
</head>
<body>
 
    <h1>Inline Event Handling</h1>
 
    <p>
        Hey 
        <a href="http://www.example.com" 
           onclick="triggerAlert('Joe'); return false;">
            Joe
        </a>
        !
    </p>
 
    <script>
        function triggerAlert(name) {
            window.alert("Hey " + name);
        }
    </script>
</body>
</html>

One common misconception with the inline model is the belief that it allows the registration of event handlers with custom arguments, e.g. name in the triggerAlert function. While it may seem like that is the case in the example above, what is really happening is that the JavaScript engine of the browser creates an anonymous function containing the statements in the onclick attribute. The onclick handler of the element would be bound to the following anonymous function:

function () {
	triggerAlert('Joe');
	return false;
}

This limitation of the JavaScript event model is usually overcome by assigning attributes to the function object of the event handler or by using closures.

Traditional model

In the traditional model, event handlers can be added/removed by scripts. Like the inline model, each event can only have one event handler registered. The event is added by assigning the handler name to the event property of the element object. To remove an event handler, simply set the property to null:

<!doctype html>
<html lang="en">
<head>
	<meta charset="utf-8">
	<title>Traditional Event Handling</title>
</head>
 
<body>
	<h1>Traditional Event Handling</h1>
 
	<p>Hey Joe!</p>
 
	<script>
		var triggerAlert = function () {
			window.alert("Hey Joe");
		};
 
		// Assign an event handler
		document.onclick = triggerAlert;
 
		// Assign another event handler
		window.onload = triggerAlert;
 
		// Remove the event handler that was just assigned
		window.onload = null;
	</script>
</body>
</html>

To add parameters:

var name = 'Joe';
document.onclick = (function (name) {
	return function () {
		alert('Hey ' + name + '!');
	};
}(name));

Inner functions preserve their scope.

DOM Level 2

The W3C designed a more flexible event handling model in DOM Level 2.

Name Description Arg. type Arg. name
addEventListener Allows the registration of event listeners on the event target. DOMString type
EventListener listener
boolean useCapture
removeEventListener Allows the removal of event listeners from the event target. DOMString type
EventListener listener
boolean useCapture
dispatchEvent Allows sending the event to the subscribed event listeners. Event evt

Some useful things to know :

  • To prevent an event from bubbling, developers must call the "stopPropagation()" method of the event object.
  • To prevent the default action of the event to be called, developers must call the "preventDefault" method of the event object.

The main difference from the traditional model is that multiple event handlers can be registered for the same event. The useCapture option can also be used to specify that the handler should be called in the capture phase instead of the bubbling phase. This model is supported by Mozilla, Opera, Safari, Chrome and Konqueror.

A rewrite of the example used in the traditional model

<!doctype html>
<html lang="en">
<head>
     <meta charset="utf-8">
     <title>DOM Level 2</title>
</head>
 
<body>
     <h1>DOM Level 2</h1>
 
     <p>Hey Joe!</p>
 
 
     <script>
          var heyJoe = function () {
               window.alert("Hey Joe!");
          }
 
          // Add an event handler
          document.addEventListener( "click", heyJoe, true );  // capture phase
 
          // Add another event handler
          window.addEventListener( "load", heyJoe, false );  // bubbling phase
 
          // Remove the event handler just added
          window.removeEventListener( "load", heyJoe, false );
     </script>
 
</body>
</html>

Microsoft-specific model

Microsoft does not follow the W3C model up until Internet Explorer 8, as its own model was created prior to the ratification of the W3C standard. Internet Explorer 9 follows DOM level 3 events, and Internet Explorer 11 deletes its support for Microsoft-specific model.

Name Description Arg. type Arg. name
attachEvent Similar to W3C's addEventListener method. String sEvent
Pointer fpNotify
detachEvent Similar to W3C's removeEventListener method. String sEvent
Pointer fpNotify
fireEvent Similar to W3C's dispatchEvent method. String sEvent
Event oEventObject

Some useful things to know :

  • To prevent an event bubbling, developers must set the event's cancelBubble property.
  • To prevent the default action of the event to be called, developers must set the event's "returnValue" property.
  • The this keyword refers to the global window object.

Again, this model differs from the traditional model in that multiple event handlers can be registered for the same event. However the useCapture option can not be used to specify that the handler should be called in the capture phase. This model is supported by Microsoft Internet Explorer and Trident based browsers (e.g. Maxthon, Avant Browser).

A rewrite of the example used in the old Microsoft-specific model

<!doctype html>
<html lang="en">
<head>
     <meta charset="utf-8">
     <title>Microsoft-specific model</title>
</head>
<body>
     <h1>Microsoft-specific model</h1>
 
     <p>Hey Joe!</p>
 
     <script>
          var heyJoe = function () {
               window.alert("Hey Joe!");
          }
 
          // Add an event handler
          document.attachEvent("onclick", heyJoe);
 
          // Add another event handler
          window.attachEvent("onload", heyJoe);
 
          // Remove the event handler just added
          window.detachEvent("onload", heyJoe);
     </script>
 
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment