There are a lot of questions and trouble about event handling that new web developers fall into not because they don't know about event handling rather they don't understand how it actually works.
In an interview, it is like a drink in a party that everyone wants to taste. The interviewer just loves it.
This is part 2 of the Javascript interview preparation.
Today, we are going to talk about event bubbling and capturing in javascript and how browser acts so that you can answer the question on the basis of what you learned from here.
Let's Start:
EVENT HANDLER:
Event handlers are the block of codes that are executed in response to the event whenever they occur. You are here mean you already know that Javascript is an event-driven language. This is because after the webpage has loaded the Javascript continues to run waiting for an event. In javascript, the flow of the program is determined by events such as user actions.
Event Handler is assigned as an attribute of the element to which the javascript code is expected to execute. The general syntax is:
example:
<button onclick="getElementById('root').innerHTML ='button clicked'">Click Here</button>
we can also call a function that performs this task.
<button onclick="changetext()">Click Here</button>
<script>
function changeText(){
var element = getElementById('root');
element.innerHTML = 'button clicked';
}
</script>
List of events and event-handlers that listen to that event.
EVENT PROPAGATION:
It's ubiquitously known thing that elements on a web browser are nested. Event fired on an element will not stop on that element rather it propagates in the tree. Event Propagation is the process of calling all event listeners in a tree attached to that node.
Event Target- Event target is the element where the event happened.
On another note-You may have also come across currentTarget anywhere don't get confused with this. The current target is different than Event target.
We will discuss it later.
Event Propagation occurs in three processes or phases. First is Capture, Second is the event target and the last one is bubbling.
Event Capturing:
The event is first Captured by outer elements and then propagated to inner elements. Capturing is also called as a trickle.
Event target: In this, related event attached to that node is triggered. Each listener will be called with the event objects that gather information relevant to the event.
Event Bubbling: The event is first captured and handled by the inner element and then propagated by the outer elements (from the inner element to all the way up to the body).
There is a popular phrase 'trickle down bubble up'.
Note: JQUERY does not have an option for capturing.
Branch determination is static, which means the branch is established at the initial dispatch of the event. Any modification in the DOM tree while event processing will be ignored.
Summary till now:
It is no doubt that propagation is bidirectional with three-phase i.e
capture phase <-> Target Phase <->Bubble Phase
It occurs with stage one after another.
Please take the time and try to understand what I said looking through the image below.
Here, the event order is of two types- one is in red and others are in blue and green respectively. The number inside the () is to show order. For example, the event capturing process is shown in red color with (1) mean it is performed first in this process. In the image, the red arrow moves all way from top-most dom to inner dom where the event took place or triggered (in our case it is td element) and then phase(2) occurs which is blue color and the last one is event bubbling shown by green place take place which is the exact opposite of Event bubbling.
focus, blur and load and some others don't bubble up. There travel stops after the target phase i.e second phase. During the event bubbling phase, only the non-capturer will be called.
elem.addEventListener(click, function, true); //elem is an element object and function is an event handler function
in this code above the third parameter is for capture. Only capture listeners are called and handled. If it is passed false, event capture is false i.e Capture phase is restricted.
** If the parameter is omitted default value is false. **
We need a proper understanding of this in our daily coding practice.
Let's look through this example:
There is
- with multiple list items inside it. Inside that list, there is information about users and button to delete that user. The click event is attached to all the delete buttons. In the due process a new list item is added, will the delete button of the newly added list work? Try to write your own code to show the answer and comment here with the result .
I have written another demo code leaving the problem above for you. In this code, we have multiple lists and we add another list with add cheese button, please look through the code carefully and try to reason why the newly added list's delete button doesn't delete.
Here you can see the result, here the cheese item is added to the list by clicking Add cheese Button.
When we add the new list HTML element is as same as the existing lists item's HTML.
Though we have attached an event listener with className 'delete' new element is not attached to the event.
What can we do in this? You might have a clue in your mind that why not add an event listener when a new element is created in function(){}? Well, this will not definitely sound engineering solution to the problem compared to the solution that attaches an event listener to the ul rather than li. Since, because of event bubbling the event will be caught by ul element anyhow. This is best for me and I can think of this as a solution not because I have done a lot of this work before but because I can think of a solution with knowledge of event bubbling.
What is the difference between the current target and event target?
The currentTarget is the element that the event listener is attached to. This is 'this' element in the event handling code. The currentTarget is the element that has an event listener. Whereas, event target is the target property of the Event interface which is a reference to the object that dispatched the event. It is different from Event.currentTarget when the event handler is called during the bubbling or capturing phase of the event.
summary of the above para is:
target = element that triggered event.
currentTarget = element that has the event listener.
Let's illustrate this with an example.
Code explanation:
function() is an anonymous function that is executed right after it is created.
In JS code line number 3, the event listener for a click is attached to element 1 and the function is passed as the second parameter. When a click event is handled, the result element's text is appended with the event target and the current target. We must be sure from now that though no click event listener is attached with element 2, the event gets bubble up and is handled by click event listener of element 1 since it has an event handler for the click event.
OUTPUT Explained:
When 1 click me is clicked, we get an output as
target: 1
currentTarget: 1
because the event is triggered by div with id 1 and also handled by event listener in the same element i.e 1.
When 2 clicks me as well is clicked we get the output as
target: 2
currentTarget: 1
because here event is triggered in div id 2 but the event is handled by div id 1. Event current target is the element where an event listener for that event is attached whereas the event target is an element where the event is fired i.e 2.
Here, we saw how we can take advantage of event bubbling in the sample code above but event bubbling is trouble sometimes.
For example, there is a table and it has rows with an email and a button with different event handlers. It is intended that when the user clicks on that table user should be redirected to another page but the clicking button shouldn't redirect to the next page. Don't look this as an application rather than a condition. How can you make a button click do nothing since click event on the button bubble up to the table and event listener in the table handle the event of a button which is bubbled up to the table?
To prevent this from happening, we should use stop propagation of the event.
e.stopPropagation()
All the listeners registered on the nodes on the propagation path that follow the current target will not be called.
There is another function that sounds similar:
stopImmediatePropagation (source: Mozilla)
The stopImmediatePropagation() method of the Event interface prevents other listeners of the same event from being called.
If several listeners are attached to the same element for the same event type, they are called in the order in which they were added. If stopImmediatePropagation() is invoked during one such call, no remaining listeners will be called.
This is what I have in mind right now. I will add more in the future.
Stay safe and alert.
Thanks for reading and feel free to comment.
Take care.
Top comments (0)