jQuery: Triggering Actions for Delegated Events

2015-05-08 JavaScript

Attaching an event handler against selector that already exists in DOM is pretty easy but what if you have to work with non-static content that is appended and injected dynamically?

Let’s assume that we have the following document structure

<html>
<body>
    <ul>
        <li><a id="link1" href="#">Static link</a></li>
    </ul>
</body>
</html>

Now, triggering an action when this particular link is clicked can look like this

$('#link1').click(function() {
	console.log('You clicked a static link!');
});

or

$('#link1').on('click', function() {
	console.log('You clicked a static link!');
});

Extremely easy, right?

So let’s append new element to the list.

$('ul').append('<li><a id="link2" href="#">Dynamic link</a></li>');

Right now, to check whether a link from dynamically loaded content has been clicked, we simply can’t use above code for selector with ID equal to

#link2

It won’t work because click event will be directly bounded instead of being delegated. When an event is delegated, it can be applied for both static and dynamic content and to achieve that you should use

$('ul').on('click', '#link2', function() {
    console.log('You clicked a dynamic link!');
});

What’s the difference? First of all we have to bind an event against ul element which is a container (parent) for all list elements we’re focus on (those that exist and those that can be added in the future). Then we have to tell jQuery into which exactly selector we want to attach an event. In this case #link2.

Read more about direct and delegated events.