Fix: jQuery .click() Event Not Working with Dynamically Added Elements

August 22, 2014

jQuery .click is one of the most simple and widely used events in the jQuery library. It works great for most of the time, but you may encounter a problem when you add dynamic elements. Let’s set up an example. Drop the following code into a text file called test.html and then open it in a browser.

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta charset="utf-8" />
  <title>jQuery Test</title>
</head>
<body>
  <p><div id="div1">ready...</div></p>
  <p><button id="btn1">Button 1</button></p>
  
  <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
  <script type="text/javascript">
  
    $(document).ready(function () {

      $('#btn1').click(function () {
        $('#div1').html('You clicked button 1');
      });

    });
  </script>
  
</body>
</html>

It’s a very simple example and when you press button 1 it displays some text in div1. No problem.

Let’s get more adventurous and instead of just text let’s add a html button dynamically into the div. Then we’ll put a .click function to handle the event. The new script section will be:

  <script type="text/javascript">
  
    $(document).ready(function () {
  
      $('#btn1').click(function () {
        $('#div1').html('<button id="btnNew">Add Button</button>');
      });
	  
      $('#btnNew').click(function () {
        alert("New Button Clicked");
      });

    });
  </script>

After you have updated the code, save it and refresh the browser. This time when you click button 1 a new button appears. When you click on the new button .. nothing!

The problem is that .click() only works for elements that already existed when the page loaded. ‘btnNew’ doesn’t exist in this context and so you cannot directly bind it. This is easy to fix: you need to delegate the event. Change the .click code to:

   $('body').on('click', '#btnNew', function () {
     alert("New Button Clicked");
   });

The .on() event is related to the .click() event but by not directly binding the event and moving to delegates we can tell jQuery how to handle a click event raised from an element known as btnNew wherever it is on the body.

Prior to jQuery 1.7 you may have used .bind(), .delegate() or .live(), but these have all been superseded and the functionality rolled into the .on() event. You can find more details on the jQuery site: http://api.jquery.com/on/#direct-and-delegated-events

The final code is:

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta charset="utf-8" />
  <title>jQuery Test</title>
</head>
<body>
  <p><div id="div1">ready...</div></p>
  <p><button id="btn1">Button 1</button></p>
  
  <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
  <script type="text/javascript">
  
    $(document).ready(function () {
	  
      $('#btn1').click(function () {
        $('#div1').html('<button id="btnNew">Add Button</button>');
      });
	  
      $('body').on('click', '#btnNew', function () {
        alert("New Button Clicked");
      });

    });
  </script>
  
</body>
</html>

 

3 thoughts on “Fix: jQuery .click() Event Not Working with Dynamically Added Elements

  1. Saurabh

    Thanks for posting this. This has been of great help. Was stuck with related issue for some time.
    Also I just wanted to ask, for using the “on” function for “click” event and “#btnNew” button, you have used “body” element. Is there any specific reason for this?

  2. Moretin

    Thank you very very much! I ran into this problem and was afraid that I could not find a decent article explaining the issue.

  3. John

    Thanks very much for posting this – solved a pesk problem for me with handling events for dynamically added list items,

Comments are closed.