views:

113

answers:

5

The function associated with the selector stops working when I replace it's contents using .html(). Since I cannot post my original code I've created an example to show what I mean...

Jquery:

$(document).ready(function(){
$("#pg_display span").click(function(){
 var pageno = $(this).attr("id");
 alert(pageno);
 var data="<span id='page1'>1</span><span id='page2'> 2</span><span id='page3'> 3</span>";
    $("#pg_display").html(data);

});
});

Html :

<div id="pg_display">
<span id="page1">1</span>
<span id="page2">2</span>
<span id="page3">3</span>
</div >

Is their any way to fix this??...Thanks

+4  A: 

Not sure I understand you completely, but if you're asking why .click() functions aren't working on spans that are added later, you'll need to use .live(),

$("#someSelector span").live("click", function(){
  # do stuff to spans currently existing
  # and those that will exist in the future
});

This will add functionality to any element currently on the page, and any element that is later created. It keeps you have having to re-attach handlers when new elements are created.

Jonathan Sampson
Thanks man exactly what I was looking for...
halocursed
You're welcome. Keep up the good work.
Jonathan Sampson
+3  A: 

You have to re-bind the event after you replace the HTML, because the original DOM element will have disappeared. To allow this, you have to create a named function instead of an anonymous function:

function pgClick() {
  var pageno = $(this).attr("id");
  alert(pageno);
  var data="<span id='page1'>1</span><span id='page2'> 2</span><span id='page3'> 3</span>";
  $("#pg_display").html(data);

  $("#pg_display span").click(pgClick);
}

$(document).ready(function(){
  $("#pg_display span").click(pgClick);
});
Philippe Leybaert
Rebinding is old-school. .live() does auto-rebinding for any elements created at a later time.
Jonathan Sampson
I know, but it's better to illustrate the problem in the context of the question. If you just suggest the .live() function, it doesn't really answer the question.
Philippe Leybaert
I don't think you offered a bad solution. Only a slightly older one. +1 to you though, since your solution does work, and works just fine with this issue.
Jonathan Sampson
A: 

Use the $("#pg_display span").live('click', function....) method instead of .click. Live (available in JQuery 1.3.2) will bind to existing and FUTURE matches whereas the click (as well as .bind) function is only being bound to existing objects and not any new ones. You'll also need (maybe?) to separate the data from the function or you will always add new span tags on each click.

http://docs.jquery.com/Events/live#typefn

nopuck4you
A: 

That's to be expected, since the DOM elements that had your click handler attached have been replaced with new ones.

The easiest remedy is to use 1.3's new "live" events.

Dave Ward
A: 

In your situation, you can use 'Event delegation' concept and get it to work.

Event delegation uses the fact that an event generated on a element will keep bubbling up to its parent unless there are no more parents. So instead of binding click event to span, you will find the click event on your #pg_display div.

$(document).ready(
    function()
    {
        $("#pg_display").click(
            function(ev)
            {
                //As we are binding click event to the DIV, we need to find out the
                //'target' which was clicked. 
                var target = $(ev.target);

                //If it's not span, don't do anything. 
                if(!target.is('span'))
                   return;                

                alert('page #' + ev.target.id);
                var data="<span id='page1'>1</span><span id='page2'>2</span><span id='page3'>3</span>";
                $("#pg_display").html(data);

            }
         );
    }
);

Working demo: http://jsbin.com/imuye

Code: http://jsbin.com/imuye/edit

The above code has additional advantage that instead of binding 3 event handlers, it only binds one.

SolutionYogi