When it comes to attaching event listeners, be it a particular element in the DOM, or a group of elements via CSS selectors, most of us bind the event listener directly to the elements. Direct binding is fine when you’re doing for a PARTICULAR element, but it may create problems for a group of elements if you’re not taking extra care while event binding. To understand the issue, let’s have a look at the following code block (Here’s a live example)
[sourcecode language=”html”]
<!– index.html –>
<div class="container" style="margin-bottom:50px;"></div>
<input type="button" value="Add More Buttons" id="addmore" />
[/sourcecode]
And we added the following javascript (depends on jQuery)
[sourcecode language=”javascript”]
;(function($){
$(document).ready(function(){
$("#addmore").on("click",function(){
var l = $(".container button").length+1;
$("<button/>").html("Click Me "+l).appendTo($(".container"));
$(".container button").on("click",function(){
alert("Clicked");
});
});
});
})(jQuery);
[/sourcecode]
Now if you add more and more buttons, you can see that it repeatedly attaching events. See the effect in the following animation
To avoid these repeated bindings, you can modify your code like this and detach all the event listeners which were attached previously to these buttons.
[sourcecode language=”javascript”]
$(".container button").off("click");
$(".container button").on("click",function(){
alert("Clicked");
});
[/sourcecode]
This is boring, lengthy and sometime risky because you have to manually detach events everytime a new DOM element which satisfies your CSS selector rule adds in the container. And if you forgot to do that, chances are higher to break something somewhere.
Now, to save from this pain, jQuery had introduced event delegation which doesn’t bind the event listener to the dom elements but it delegates the event from their parent. This way, you will never have to worry about detaching previous attached event listeners anymore. Let’s have a look at our final code block, and here is a live example too
[sourcecode language=”javascript”]
;(function($){
$(document).ready(function(){
//event delegation
$(".container").on("click","button",function(){
alert("Clicked");
});
$("#addmore").on("click",function(){
var l = $(".container button").length+1;
$("<button/>").html("Click Me "+l).appendTo($(".container"));
});
});
})(jQuery);
[/sourcecode]
In the above example see how we have delegated the click event to every “button” in the container div. Once the delegation is done, it doesn’t matter whenever a new dom element (in this case, a “button”) inserts in the container. It will always capture the “click” event because the parent div “.container” will delegate that event to it properly. All you have to do is select a parent element, and then delegate the event to childrens (via CSS selector) belonging to it. It’s the same .on() method, just takes an extra parameter in the middle which represents the CSS selector to which the event will be delegated.
[sourcecode language=”javascript”]
//event delegation
$(".container").on("click","button",function(){
alert("Clicked");
});
[/sourcecode]
By using event delegation in jQuery for a group of DOM elements, you can avoid risks, keep your code cleaner and save yourself from some overkill every time. Hope you’ve liked this article 🙂