Event in Javascript — Part1

Vikash Agarwal
5 min readDec 29, 2015

--

In web applications there mainly are two things

  • What user can see
  • What user can do

We present the html to the user and waits for the user to perform some action on the html. When user performs some action, we capture it with the help of events. We register for the events and do some task like making an AJAX call, showing popup dialog, sorting, searching etc. Lets see how to deal with events.

Below are the topics I am going to cover

  • How to register for an event
  • How to remove an event listener
  • Phase of Event — Flow of Event
  • Event Object
  • stopPropagation(), stopImmdediatePropagation()
  • preventDefault()
  • Creating Custom Event
  • Trigger an Event
  • Event Delegation
  • Some performance guidelines

Register for an Event — addEventListener()

Three things are required to register an event.

  • target element
  • type of event
  • listener function
function buttonClickHandler(event){
alert("Button is clicked");
}
var buttonElem = document.getElementById("button");
buttonElem.addEventListener("click",buttonClickHandler);

JS Fiddle Link :- https://jsfiddle.net/vikash20186/ymj9srat/

Javascript gives us the addEventListener API which is used to register an event. It’s defined on every DOM element, window and document object.It takes three parameter which are event name, listener function reference & capture mode flag.

addEventListener(event, listenerFunction, captureMode);

Last parameter is optional which has default value as false. I will get to it later.

There are lots of events provided by the javascript like

  • click, mouseover, mouseout
  • keydown, keypress, keyup
  • load, unload, error
  • DOMContentLoaded, ready
  • touchStart, touchEnd

and the list goes on. These are the common ones which we mostly use in our application. Once you define an event listener function, it will always remain in the memory unless you remove it or page is unloaded from the browser.

we can have multiple listener function on the same target.

removeEventListener

Similar to addEventListener, JS provides removeEventListener function to remove an event handler. For Ex

function buttonClickHandler(event){
alert("Button is clicked");
}
function init(){
var buttonElem = document.getElementById("button");
var removeButtonElem = document.getElementById("removeEventBtn");
buttonElem.addEventListener("click",buttonClickHandler);
removeButtonElem.addEventListener("click" , function(){
buttonElem.removeEventListener("click",buttonClickHandler);
});
}
init();

removeEventListener(event, listenerFunction, captureMode);

removeEventListener has same signature as addEventListener. For removeEventListener to work, signature has to match exactly as addEventListener. same event type, same listener function reference and same capture mode. In my example above if you notice, buttonElem has same event type and function reference while registering for an event and removing the event. If there is any mismatch then event wont be removed. For example, below wont work

function buttonClickHandler(event){
alert("Button is clicked");
}
var buttonElem = document.getElementById("button");
var removeButtonElem = document.getElementById("removeEventBtn");
buttonElem.addEventListener("click",buttonClickHandler);
removeButtonElem.addEventListener("click" , function(){
buttonElem.removeEventListener("click",function(event){
alert("Button is clicked");
});
});

JS Fiddle Link :- https://jsfiddle.net/vikash20186/k2z9cfw2/

In this case, removeEventListener will not work because same function is not used while remove the event. Even though the function looks same, its different reference. There are exactly two copy of same function. In case if you run into issue in removing your event listener, you should check about the signature first.

If we have multiple listener functions and we want to remove all of them then, we have to remove all of the listener function in the same way we added it.

Phase of event — Flow of event

this is an interested thing to know how event flows in the application.

<!doctype html>
<html>
<head>
<title>Flow of events</title>
</head>
<body>
<p> This is a paragraph </p>
<div id="div">
<button id="frst"> First button inside div</button>
<button id="second"> Second button inside div</button>
</div>
</body>
</html>

the DOM representation of the above HTML is

DOM Representation

Lets say user clicks on second button, browser will create a click event and then it will pass the event to the button element which created it.

An event always start from the root of the DOM tree and it traverses to the target element and then comes again the same path. It starts from the

window -> document -> HTML -> Body -> DIV -> Second Button.

It reaches the second button which created the event and then it come back to the window using the same route in the reverse order.

second button -> DIV -> Body -> HTML -> document -> window.

So the full path is window -> document -> HTML -> Body -> DIV -> Second Button ->DIV -> Body -> HTML -> document -> window.

Flow represented by red line.

The flow is divided into three phases

  • Capturing phase — first part of the flow, where event traverses from the window to the target element
  • Targeting phase — second part of the flow, where it reaches the target element and then starts flowing back.
  • Bubbling phase — third part of the flow, where it traverses from the target element to the window.

We can capture the event in capturing or bubbling phase which we can specify in addEventListener function as the third parameter. third parameter is an optional parameter which takes a boolean value. Default value of this parameter is false. If we don’t specify it or mention false, then it registers the listener function in the bubbling phase. if we say true, then it registers in the capturing phase. We can specify listener function in both the phase. If so, capture mode will be executed first.

When event traverses through different node, at each node it checks

  • if there is any listener function attached to the node for the event generated
  • if there is a listener function, then is it matching the phase or not
  • if matches, then it executes the listener function first and then move on the next node.
var secondButtonElem = document.getElementById("second");
var divElem = document.getElementById("div");
secondButtonElem.addEventListener("click",function(){
console.log("button is clicked")
});
divElem.addEventListener("click",function(){
console.log("div is clicked")
});

JS Fiddle Link :- https://jsfiddle.net/vikash20186/ymj9srat/

In the above code, we are registering click event listener function to div and button which is child of div element. When user clicks on this button, browser creates click event and then sends from the window to the target element and back to the window.

This is what happens when user clicks

  • Browser creates mouse click event object
  • It starts the capturing phase from the window and check if there is any click event listener function attached to the window. If yes, it executes the function. In our example, we don’t have any for widow.
  • Similarly it goes to document, then html, then body & then div element.
  • When event reaches div element, there is a click listener function present, it checks the phase is matching the capture phase or not. Since the function is not registered for capture phase, it goes to the button element without doing anything.
  • Here it meets the target element and changes the phase from capturing to the targeting phase. Here it will not check for phase of event listener and it executes the listener function if present. In our example, it executes the function of button which logs, “button is clicked” in the console.
  • It starts going back, and goes to divElem. It checks again for the listener function for bubbling phase. Since we have a function registered for the bubbling phase, it executes the listener function and then continue to body, html, document and window.

We can have multiple listener function for same DOM element and in same phase, it executes them in the same order in which they have registered.

JS Fiddle Link :- https://jsfiddle.net/vikash20186/ymj9srat/2/

Read my second link on event @ Event In Javascript- Part2

--

--