How to Bind Events to Dynamically Created Elements in JavaScript

HTML events allow you to create interactive websites and applications. They enable you to add dynamic functionality to your web pages such as button clicks, on hover, click and drag and more. However, often web developers need to bind events to dynamically created page elements. In this article, we will learn how to attach events to dynamic page elements.

What is Event Binding to Dynamic Elements

JavaScript allows you to bind numerous events to HTML elements such on click, on hover, on change, etc. using event handlers. They are already available to each DOM element created during page load. We just need to call them and define their processing. But all these event handlers can be attached only to DOM elements already present on the page at the time of loading. If you attach an event handler to a dynamically added element, that is added via DOM JavaScript, AJAX or other means, then the default event handler will not bind to the new element. That is why you need a different approach to attach event handlers to dynamic events.

For example, let us say you have a list of links on a page where you display helpful text message on hovering over each link. This may be because you have added an event handler that displays the message whenever anyone hovers over a link on the web page. Let us say you dynamically add a new link to your page. You will see that the new link does not display any message when you hover over it. That is because the default HTML event handlers are not applicable to dynamically created elements. But in today’s web development, most of the DOM elements are dynamically created, whether it is content, link, div or something else. Therefore, it is essential to bind events to dynamically created elements.

What is Event Delegation

There are several ways to handle events triggered by dynamically created elements. However, they mostly use event delegation. Typically, we attach event handler directly to the DOM elements present on web page. But in case of dynamically created elements, you need to attach the event to its parent or an ancestor that is already present when your page is loaded (static). The event handler is triggered whenever the event is triggered on the element or any of its descendants. In the event handler, we check if the element which triggered the element matches the selector, to run the handler function. This is known as event delegation.

How to Bind Events to Dynamically Created Elements

We will learn how to bind events to dynamic DOM elements using plain JavaScript as well as popular JS library jQuery. Let us say you have the following HTML page.

<html>
<head><script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"> </script></head>
<body>
<ul id="links">
<li class="static-link">Static List item</li>
</ul>
</body>

<script type="text/javascript">
// Create the new element
var ul=document.getElementById('links');
var li = document.createElement('li');
li.className = 'dynamic-link'; // class name
li.innerHTML = 'Dynamic List Item'; // inner text
ul.appendChild(li); // append element
</script>

</html>

In the above code, we have simply created an unordered list with one static list item. We use JavaScript to add a dynamic list item. We have also imported jQuery library since we will need it later.

1. Using jQuery (Event Delegation)

jQuery provides a simple yet powerful function on() that allows you to easily add event handlers to dynamic elements, using event delegation. Here is its syntax.

$(static_ancestor).on(event, element, function() {});

The above on() function is called on a static ancestor of the dynamic element. It accepts 3 arguments – event name, selector for dynamic element and the event handler function. Here is an example to add ‘on hover’ event to the dynamic list item that displays an alert box with ‘hello’ message. For this purpose, add the following line to <script> tag.

$('#links').on('click', 'li', function() {alert('hello')});

Here is the full code.

<html>
<head><script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"> </script></head>
<body>
<ul id="links">
<li class="static-link">Static List item</li>
</ul>
</body>

<script type="text/javascript">
// Create the new element
var ul=document.getElementById('links');
var li = document.createElement('li');
li.className = 'dynamic-link'; // class name
li.innerHTML = 'Dynamic List Item'; // inner text
ul.appendChild(li); // append element

$('#links').on('click', 'li', function() {alert('hello')});
</script>

</html>

Now, when you click any of the list items – static or dynamic, it will show an alert box with ‘hello’ message. If you want to add event handler only to dynamically added list item, you will have to customize your selector to select only those list items as shown below. Here is an example where we have only added class name selector for list item, instead of specifying list item tag in selector. This will select only the dynamic list item and not the static one.

$('#links').on('click', '.dynamic-link', function() {alert('hello')});

If you are unable to find a stable ancestor to your dynamic element, you can call on() function DOM elements like document or body which represent the full page.

2. Using JavaScript (Event Delegation)

In this case also, we attach the event handler to a static ancestor of dynamic element as shown below. Add the following JS code to your page’s <script> tag.

var ul=document.getElementById('links');

ul.addEventListener('click',function(e){
if(e.target.classList.contains('dynamic-link')){
alert('hello');
}
});

In the above code, we add event listener to the parent list tag ul, for click event. When any of its child elements, that is, list items are clicked, then it will check the class name of the clicked element. If it matches ‘dynamic-link’, then it will display alert box. So your full code will look like the following.

<html>
<head><script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"> </script></head>
<body>
<ul id="links">
<li class="static-link">Static List item</li>
</ul>
</body>

<script type="text/javascript">
// Create the new element
var ul=document.getElementById('links');
var li = document.createElement('li');
li.className = 'dynamic-link'; // Class name
li.innerHTML = 'Dynamic List Item'; // Text inside
ul.appendChild(li); // Append it

//add event listener
ul.addEventListener('click',function(e){
if(e.target.classList.contains('dynamic-link')){
alert('hello');
}
});

</script>

</html>

In this case, the event handler is added only to those elements containing class name ‘dynamic-link’ and not all list items. So this allows you to precisely target dynamic items for event handling.

3. Using Inline Event Handlers

In this approach, we simply add the event handler while dynamically creating new element itself. First we define the event handler.

function dynamic_event() {
alert('hello');
}

Then we attach the event to element when we dynamically create it. Here we call dynamic_event function on onclick event.

var ul=document.getElementById('links');
var li = document.createElement('li');
li.className = 'dynamic-link'; // class name
li.innerHTML = dynamicValue; // inner text
$('#links').appendChild(li); // append element
li.onclick = dynamic_event; // attach event

In this case, the event handler is applied only to the element where its is attached and not all elements, as is the case with event delegation. So it gives you better control over event handling of dynamic elements.

Here is what your full code will look like.

<html>
<head><script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"> </script></head>
<body>
<ul id="links">
<li class="static-link">Static List item</li>
</ul>
</body>

<script type="text/javascript">
// Create the new element
var ul=document.getElementById('links');
var li = document.createElement('li');
li.className = 'dynamic-link'; // class name
li.innerHTML = 'Dynamic List Item'; // inner text
ul.appendChild(li); // append element

li.onclick = dynamic_event; // attach event


function dynamic_event() {
alert('hello');
}
</script>

</html>

Useful Points in Event Binding

Here are some best practices to consider while binding events to dynamic elements.

  1. Event Delegation vs Inline Events – If you have a small number of dynamic elements, you can use event delegation since it is easily customizable and separate from DOM creation. If you have a large number of dynamically created items, say, a table of million rows added dynamically, then it is better to add inline event handler. Event delegation requires searching linearly to find the suitable element that triggered event. This will affect performance as dynamic elements increase on your page. Inline events work directly on the said element and does not require any lookups.
  2. Pick Nearest Ancestor – Try adding event handler to parent or nearest ancestor of dynamically created element. This will make it easy for browser to quickly find the appropriate dynamic element. Avoid using document and body elements since it will mean the event handler is applicable for elements on entire page, and will affect performance. In this case, for every event on your page’s body, the browser will have to scan all its descendants to see if there are any event handlers to be triggered.
  3. Review Event Nesting – Since Event delegation applies event handler to all descendants of an element, it is possible that a given dynamic element will end up having multiple event handlers for same kind of event. This can cause undesirable output. So it is good to review which event handlers are triggered for your dynamic elements.

Conclusion

In this article, we have learnt several simple ways to easily bind events to dynamically created DOM elements. JavaScript allows you to add event listener both during and after creating dynamic elements, whereas jQuery allows you to add event handler after adding the element. There are two ways to add event handlers to dynamic elements – using event delegation after element is added or using inline event handlers during element creation. It is important to understand that depending on the kind selectors you define, such event binding also applies to elements that are not dynamically created. In any case, the above solutions should help you add event handlers to the dynamic elements on your web pages.

Also read:

How to Improve Website Loading Speed in Mobile
Top 5 Server Monitoring Tools
How to Choose Web Hosting Service
How to Prevent SEO Bots from Crawling Your Site