Featured post

Closures, Lexical Scoping And Scope chain In JavaScript

Closures...You have heard a lot, or might have tried to study from different sources, but failed to get the point. Well to under...

Thursday 11 February 2016

Event Handling in JavaScript (Part 1)


In this post I will cover some basic fundamentals of Event Handling and what are the different techniques of registering events.

Client side JavaScript program use an asynchronous event-driven programming model. If anything interesting happens to a document or window or element, browser generates an event for it. That event gets registered in event loop. Browser then fires event handler function for topmost event from event loop.

Lets understand above process in simple words. Event is something which is fired when user interacts with browser. Event can be click on button, hover on link, scroll on window, load of document, etc. If you want to perform any particular task on any event then you can write a function for that event. That function will be termed as Event Handler or Event Listener for that event.
If you fire lot of events back to back then browser will register all those event in a queue and will execute their event handler function one by one. That queue is called as Event Loop. Since JavaScript does not support multi tasking, those event handler functions will execute one after another.
Event Type is a string that specifies what kind of event occurred. Type "mousemove" signifies movement of mouse, "keydown" means key on the keyboard is pressed down and etc. Event Type sometimes called as Event Name.
Event Target is an object on which event has occurred or with which event is associated. Load event on Window, load event on document, click event on button etc. Some common event targets are Window, document or html element objects.
Event Object is an object that is associated with particular event and contains details about the event. Event Objects are passed as an argument to the event handler function. All event Objects have a type and target property. Type property specifies the event type and target property specifies Event target. (In IE8 or before use srcElement instead of target).
Event Propagation is process in which browser identifies objects on which event handler function should be triggered upon. Event Propagation is mostly confused as synonym of Event Bubbling but Event Propagation is much wider concept.
Event Propagation also includes the concept of Event Capturing which is opposite to Event Bubbling.


Event Bubbling and Event Capturing:
Suppose click event has occurred on anchor tag, browser will execute handler for that event. Now event will bubble up to the enclosing element of anchor tag maybe <p> tag, now handler for <p> tag will be executed. Again event will bubble up to the enclosing element of <p> tag, that could be <div> tag. Handler for <div> tag will now get executed. This process is event bubbling.
Event Capturing is opposite process of event bubbling. First handler for highest hierarchy element will get executed, then bubbles down to child element and this process goes on until it reaches to the parent of the element on which event has occurred initially. Interesting part is handler function of element on which originally event has occurred will not get executed.
Event capturing provides an opportunity to peek at events before they are delivered to their targets. A capturing event handler can be used for debugging.

Registering Event Handlers


You can register JavaScript Event Handlers in two different ways, set a property on the object or document element that is the event target or pass the handler to a method of the object or element. There are two versions of each technique.

 

Setting Event Handler Properties:

Easiest way to register an event handler function is by setting the Event name property of Event target to the desired event handler function.

Event target properties have name that consists of "on" prefix like, onmouseover, onclick, onhover etc. Event targets as earlier mentioned can be window, document etc.

window.onload = function() {
   
      // Look up an div tag with id header
      var header = document.getElementById("header");
      console.log(header);      // Printing element
}

This technique works for all kinds of browsers but it has some shortcomings. It won't allow you to register more than one type of event handler function for any event on particular event target. Means?? You can register only one event handler function for onload event on window object. If you are writing a library just go for addEventListener() method (Will explain this technique later in the post).

 

Setting Event Handler Attributes:

Another popular way of registering event is by setting attribute on corresponding HTML tag. Like:

<button type="submit" id="ironman" onclick="alert(I am IronMan!);">Identify</button>
<button type="submit" id="spiderman" onclick="greatPower()">Famous Dialog</button>
<script>
      var greatPower = function() {
            alert("Power is directly proportional to Responsibility. :p");
      }
</script>

There are lot of things to remember in order to use this technique.
  • Attribute value should always be JavaScript String
  • If there are multiple statements in attribute value then separate them with semicolon ;
  • Last thing to remember, you are mixing JavaScript code with HTML content. Some programmers avoid this technique in order to keep their code clean

 

addEventListener():

Here comes the technique which I will suggest you to use. This technique is supported by all the browsers other than IE8 and below. All Objects like window, document and other document elements has addEventListener method defined. This method takes three parameters, first: event name (prefix "on" is not used in the name of the event), second: event handler function, third: a Boolean value determining whether the event registered as an capturing event or not. You are wondering about the third parameter. Right? If passed true, event will registered as an capturing event else not. Basically capturing handlers of the window object are invoked first, then the capturing handlers of the document object, then the body object, and so on down the DOM tree until the capturing event handlers of the parent of the event target are invoked. Capturing event handlers registered on the event target itself are not invoked.

<button id="myButton" type="submit" value="submit">Submit</button>
<script>
      var b = document.getElementById("myButton");

       var clickHandler = function() {
             alert("Please do not block ads on this blog.");
      }
 
      b.addEventListener("click", clickHandler, false);

</script>

addEventListener() is paired with removeEventListener() method that expects the same three arguments but removes the event handler function from the object rather than adding it.

 

attachEvent():

Internet prior to IE9 does not support addEventListener() or removeEventListener(). Instead it uses attachEvent() or detachEvent() methods. There are some minor differences between these two method's implementation. 

Internet Explorer does not support Event Capturing, therefore there is no third parameter required in attachEvent() and detachEvent().
Unlike addEventListener(), attachEvent() takes prefix "on" in event name.
attachEvent() allows same event handler function to be registered more than once, allowing registered function to be invoked as many times as it was registered.

<button id="myButton" type="submit" value="submit">Submit</button>
<script>
      var b = document.getElementById("myButton");

       var clickHandler = function() {
             alert("Please do not block ads on this blog.");
      }

       if(window.addEventListener) {
              b.addEventListener("click", clickHandler, false);
        } else if(window.attachEvent) {
               b.attachEvent("onclick", clickHandler);
       }
</script>

Above code will ensure that if browser supports addEventListener() than it will use that method only else it will go attachEvent method. This practice makes your application backward browser compatible.

In next post we will explore the Event Handler Invocation process..

No comments: