tags:

views:

418

answers:

3

When I replaceWith an element to bring one out of the DOM, then replaceWith it back in, events registered to it do not fire. I need to events to remain intact.

Here's my Javascript:

var replacement = $(document.createElement('span'));
var original = $(this).replaceWith(replacement);

replacement
    .css('background-color', 'green')
    .text('replacement for ' + $(this).text())
    .click(function() {
        replacement.replaceWith(original);
    });

Live demo

In the demo, when you click an element, it is replaced with another element using replaceWith. When you click the new element, that is replaced with the original element using replaceWith. However, the click handler does not work any more (where I would think it should).

+3  A: 

Because when you replace the original element, events bound to it are removed. You'll need to re-attach the click event handler on original after the call to replacement.replaceWith(original):

$(function() 
{   
   function replace() 
   {
      var replacement = $(document.createElement('span'));
      var original = $(this).replaceWith(replacement);

      replacement
         .css('background-color', 'green')
         .text('replacement for ' + $(this).text())
         .click(function() 
         {
            replacement.replaceWith(original);
            original.click(replace);
         });
   }

   $('.x').click(replace);
});
Shog9
I wish there were an automatic/elegant way of doing this. I guess this solution will have to do.
strager
@strager: You could try Matt's live events suggestion, or implement a targeted version for your own purposes. There are serious (and unpleasant) side-effects in *certain browsers* if you fail to detach events from detached elements, so you really do want it to work this way.
Shog9
+1  A: 

live events are what you are looking for

Matt
May be what I need. I'll look into it.
strager
Didn't seem to work. Odd. =S
strager
A: 

You can use live() and bind() events, this is your new code:

$(function() {
$('.x').live('click', function() {
    var replacement = $(document.createElement('span'));
    var original = $(this).replaceWith(replacement);

    replacement
        .css('background-color', 'green')
        .text('replacement for ' + $(this).text())
        .bind('click', function() {
            replacement.replaceWith(original);
        });
});
});

-Live event works with jQuery 1.3 and upper.

-if you want to stop the live propagation use die() function.

Amirouche Douda