Menu
A Cross-Browser Solution for Handling JavaScript Events

It all starts with attaching event listeners to elements. Say you have a button that increments a counter each time you click it. You can add an inline onclick attribute and that will work across all browsers but will be violating the separation of concerns and the progressive enhancement. So you should strive for attaching the listener in JavaScript, outside of any markup.

Say you have the following markup:

<button id="clickme">Click me: 0</button>

You can assign a function to the onclick property of the node, but you can do this only once:

var b = document.getElementById('clickme'), count = 0;
b.onclick = function()
{
   count += 1;
   b.innerHTML = "Click me: " + count;
};

If you want to have several functions executed on click, you cannot do it with this pattern while maintaining loose coupling. Technically you can check if onclick already contains a function and if so, add the existing one to your own function and replace the onclick value with your new function. But a much cleaner solution is to use the addEventListener() method. This method doesn't exist in IE up to and including version 8, so you need attachEvent() for those browsers.

When we looked at the init-time branching pattern (Chapter 4) you saw an example of implementing a good solution for defining a cross-browser event listener utility. Without going into all the details right now, let's just attach a listener to our button:

var b = document.getElementById('clickme');
if(document.addEventListener)
{
   b.addEventListener('click', myHandler, false);
}
else if(document.attachEvent)
{
   b.attachEvent('onclick', myHandler);
}
else
{
   b.onclick = myHandler;
}

Now when this button is clicked, the function myHandler() will be executed. Let's have the function increment the number in the "Click me: 0" button label. To make it a little more interesting, let's assume we have several buttons and a single myHandler() for all of them. Keeping a reference to each button node and a counter for the number will be inefficient, given that we can get that information from the event object that is created on every click.

Let's see the solution first and comment on it after:

function myHandler(e)
{
   var src, parts;

   e = e || window.event;
   src = e.target || e.srcElement;

   parts = src.innerHTML.split(": ");
   parts[1] = parseInt(parts[1], 10) + 1;
   src.innerHTML = parts[0] + ": " + parts[1];

   if(typeof e.stopPropagation === "function")
   {
      e.stopPropagation();
   }
   if(typeof e.cancelBubble !== "undefined")
   {
      e.cancelBubble =  true;
   }

   if(typeof e.preventDefault === "function")
   {
      e.preventDefault();
   }
   if(typeof e.returnValue !== "undefined")
   {
      e.returnValue = false;
   }
}

There are four parts in the event handler function:

First, we gain access to the event object, which contains information about the event and the page element that triggered that event. This event object is passed to the callback event handler, but not when using the onclick property where it's accessible through the global property window.event instead.

The second part is doing the actual work of updating the label.

Next is canceling the propagation of the event. This is not required in this particular example, but in general if you don't do it, than the event bubbles up all the way to the document root or even the window object. Again we need to do it two ways: the W3C standard way (stopPropagation()) and then differently form IE (using cancelBubble).

Finally, prevent the default action, if this is required. Some events (clicking a link, submitting a form) have default actions, but you can prevent them by using preventDefault() (or for IE, by setting returnValue to false).

As you can see there's quite a bit of duplicate work involved, so it makes sense to create your event utility with facade methods as discussed in Chapter 7.

This is an excerpt from JavaScript Patterns: Build Better Applications with Coding and Design Patterns

What's the best approach for developing an application with JavaScript? This book helps you answer that question with numerous JavaScript coding patterns and best practices. If you're an experienced developer looking to solve problems related to objects, functions, inheritance, and other language-specific categories, the abstractions and code templates in this guide are ideal - whether you're using JavaScript to write a client-side, server-side, or desktop application.

JavaScript Patterns includes practical advice for implementing each pattern discussed, along with several hands-on examples. You'll also learn about anti-patterns: common programming approaches that cause more problems than they solve.

Explore useful habits for writing high-quality JavaScript code, such as avoiding globals, using single var declarations, and more
Learn why literal notation patterns are simpler alternatives to constructor functions
Discover different ways to define a function in JavaScript
Create objects that go beyond the basic patterns of using object literals and constructor functions
Learn the options available for code reuse and inheritance in JavaScript
Study sample JavaScript approaches to common design patterns such as Singleton, Factory, Decorator, and more
Examine patterns that apply specifically to the client-side browser environment

Reader K. Wegrowskion says, "This book is everything I had expected it to be, and more! First off: Everything is explained very clearly and concisely. Huge plus when it comes to such a huge and sometimes very tangled subject like Javascript. Second: The fact that the book always shows both sides of the coin: the good and the bad - just so you know exactly what NOT to do, and an idea of what you're supposed to do, as well. I would recommend this title to anybody looking to learn or expand their knowledge of Javascript! Also to be noted: This is the sort of book that you don't really have to read from cover to cover - You can easily use this book as a reference for when you need to remember how certain things should be done. I know this is the case for most "{Insert Programming Language Here} Patterns" books, but I just thought I'd make that abundantly clear.

For more information click here.


Learn more at amazon.com

More Java Script Code:
• A Brief Introduction to HTML for JavaScript Programmers
• Regular Expressions Boundaries
• Easy Picture Panning Code
• JavaScript 24-Hour Trainer
• Working With the Keyboard in Java Script
• JavaScript Code to Save and Load a Table Using HTML5 Web Storage
• A Cross-Browser Solution for Handling JavaScript Events
• Code to Block the Ad Blockers
• Java Script to Get Selected Item from Drop-down Select List
• Regular Expressions Lookarounds