8

I have 3 files:

  • js_json.js -> for my json code
  • javascript.js -> for my javascript function
  • index.php

Here the code for js_json.js:

$(function(){
    $('#postTitle').change(function(){

        var title_id = $("#postTitle").val();


        $.ajax({
            type:"post",
            url:"proses.php",
            data:"title_id=" + title_id,
            dataType:"json",
            success:function(data){
                body="";
                //$.each(data, function(i,n){
                    //body = n['body'];    
                //});
                body += "<a href=\"javascript:void(0);\" id=\"pesan\" name="pesan" onClick=\"\">Hola Test</a>";
                $(".postBody").empty();
                $(".postBody").append(body);
            },
            error:function(data){
                $(".postBody").empty();
                $(".postBody").append("NO Post Selected.");
            }

        });
        return false;
    });
});

and here my javascript.js code:

$(function (){
    $("a[name=pesan]").click(function (){
        alert("holalalalalal.....!");    
    });
});

and here the index.php code:

    //some code
    <body>
        <a href="javascript:void(0);" id="pesan" name="pesan">Hola Test 1</a>
        Posts : <br />
        <select name="title" id="postTitle">
            <option value="">Select Post...</option>
            <?php
                $sql = "SELECT id, title FROM posts ORDER BY title";
                $query = mysql_query($sql) or die(mysql_error());

                while($rows = mysql_fetch_array($query)){
                    print('<option value="' . $rows['id'] . '">' . $rows['title'] . '</option>');
                }
            ?>
        </select>
        <br />
        Body : <br />
        <div class="postBody">
            Will show the body of post.
        </div>
    </body>
</html>

and my question is:

When I click the link "Hola Test 1", it works and the message appears. The problem is, after I click the select option, and the link "Hola Test" appears, and then I click that ("Hola Test") link, the message does not appear and there are no errors in firebug...

Can somebody explain to me why...? Thank's...

Matt
  • 74,352
  • 26
  • 153
  • 180
Sindhu13
  • 97
  • 1
  • 1
  • 8
  • Use `.live()` as [@Matt](http://stackoverflow.com/questions/6173238/jquery-event-not-firing/6173263#6173263) answered, but keep in mind that it is invalid to use the same id in a page more than once (*ids are unique*), and will more than likely cause other problems in the future.. – Gabriele Petrioli May 30 '11 at 07:19

2 Answers2

23

click() will only bind the event for elements that exist in the page at the time click is called (the same goes for on() without a selector, bind(), and all the other methods in the shortcut-group for bind; keydown(), change() etc. ).

Because your other element is getting added via AJAX some time later, the handler isn't bound for it.

Use .on() with a selector instead, which will bind the event to all current and future elements matched by the selector.

$(function (){
    $(document).on('click', 'a[name=pesan]', function () {
        alert("holalalalalal.....!");    
    });
});

Since on() was introduced in jQuery 1.7, if you're using earlier versions of jQuery (like those that existed when this question was asked), you can use live() or delegate() instead of on;

$(function (){
    $('a[name=pesan]').live('click', function () {
        alert("holalalalalal.....!");    
    });
});
Matt
  • 74,352
  • 26
  • 153
  • 180
  • thank's, it work... and thank you for the explanation... that's what I was looking for.... – Sindhu13 May 30 '11 at 07:10
  • thanks for this! I got stuck before by using 'on' directly to the element like: $( "p" ).on( 'click', function() {} ); any explanation why? I noticed that Chrome is throwing this warning: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check http://xhr.spec.whatwg.org/. – Loreto Gabawa Jr. Oct 16 '15 at 15:59
2

I want to mention (because I found no mention of it in any of the "event not firing" cases I scoured the web for) that there is a possibility which might bite you.

If you happen to use .remove() to extract something temporarily from the DOM and then reinsert it, then you will lose your events. What you need to use instead is .detach() to preserve the data and events after reinsertion. This can be hard to debug as everything may look normal, and the event debugging tools are sketchy at best.

(Personally I would call them something more like .detachAndScrubDataAndEvents() and .detach(), as I'm a fan of descriptive names saving hours of debugging. For those who find .remove() and .detach() to be semantically and meaningfully distinguished names... peace be with you... BUT you're flat out wrong.)