views:

309

answers:

4

I am writing a plugin and need to live bind a click. The plugin works fine when I do a normal click bind, but not a live bind.

I've boiled the plugin down to the basics:

(function($) {
  $.fn.liveBindTest = function() {
    return this.each(function() {
      $(this).live('click', function(){
        console.log('live click');
        return false;
      });
      $(this).click(function(){
        console.log('click');
        return false;
      });
    });
  };
})(jQuery);

When I call the plugin function on a link, only click is printed to my console.

What must I do in order for live() to work? Thanks.

+1  A: 

Any particular reason you have 2 click event binded into a single object? The second bind will overwrite the live bind, so the live will never fired.

Donny Kurnia
The 2 `click` events are include for the sake of example. Comment out the `click` bind, leaving the `live` bind, and the `live` bind still won't fire.
chipotle_warrior
+1  A: 

After thinking this through, I realized it makes no sense to call live on an existing DOM element because it's already in the DOM.

Trick is to use live when invoking the plugin:

(function($) {
  $.fn.liveBindTest = function() {
    return this.each(function() {
      $(this).click(function(){
        console.log('click');
        return false;
      });
    });
  };
})(jQuery);
$('a').live('click', function(){ $(this).liveBindTest(); });
chipotle_warrior
That was the perfect solution. Thanks!
Ryan Riley
please see my answer for a better solution.
return1.at
A: 

I think it's not a good point of view. Now suppose that your plugin is a sort of lightbox,and it is looking to anchor elements inside the DOM. Usually at the dom ready you will do something like

$(dom_elements).myplugin();

What if your appending some links via jsor ajax to your page? I don't think that rebinding using your

$('a').live('click', function(){ $(this).liveBindTest(); });

is going to be the right way!It will work but telling the truth i don't think that it will be a "best practice". The real problem is that with jQuery 1.4.2 the live event delegation is waiting for a string('a.test') and not for an object(this).Could it be a jQuery 1.4.2 bug?

marco
A: 

this works without workarrounds outside of the plugin:

(function ($) {
    $.fn.liveBindTest = function () {
        return this['live']('click', function () {
            console.log('click');
            return false;
        });
    };
})(jQuery);

$('a').liveBindTest();
return1.at