javascriptjqueryevents

Click event doesn't work on dynamically generated elements


<html>
<head>
    <script type="text/javascript" src="jquery.js"></script>
    <script type="text/javascript">

        $(document).ready(function() {

            $("button").click(function() {
                $("h2").html("<p class='test'>click me</p>")
            });   

            $(".test").click(function(){
                alert();
            });
        });

    </script>
</head>
<body>
    <h2></h2>
    <button>generate new element</button>
</body>
</html>

I was trying to generate a new tag with class name test in the <h2> by clicking the button. I also defined a click event associated with test. But the event doesn't work.

Can anyone help?


Solution

  • The click() binding you're using is called a "direct" binding which will only attach the handler to elements that already exist. It won't get bound to elements created in the future. To do that, you'll have to create a "delegated" binding by using on().

    Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time.

    Source

    Here's what you're looking for:

    var counter = 0;
    
    $("button").click(function() {
        $("h2").append("<p class='test'>click me " + (++counter) + "</p>")
    });
    
    // With on():
    
    $("h2").on("click", "p.test", function(){
        alert($(this).text());
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
    <h2></h2>
    <button>generate new element</button>

    The above works for those using jQuery version 1.7+. If you're using an older version, refer to the previous answer below.


    Previous Answer:

    Try using live():

    $("button").click(function(){
        $("h2").html("<p class='test'>click me</p>")
    });   
    
    
    $(".test").live('click', function(){
        alert('you clicked me!');
    });
    

    Worked for me. Tried it with jsFiddle.

    Or there's a new-fangled way of doing it with delegate():

    $("h2").delegate("p", "click", function(){
        alert('you clicked me again!');
    });
    

    An updated jsFiddle.