Search code examples
jqueryjquery-pluginsliveplugin-pattern

jQuery plugin pattern using "live"


I have red many articles about writing object oriented javascript code and developing jQuery plugin, so far so good, I understand how they work and I can create my own plugins.

But, there is one problem with all the articles ( even with official plugin authoring guide - http://docs.jquery.com/Plugins/Authoring ) - these all patterns don`t support "live".

Let`s take for example this pattern - http://www.virgentech.com/blog/2009/10/building-object-oriented-jquery-plugin.html

$.fn.myplugin = function(options)
{
   return this.each(function()
   {
       var element = $(this);

       // Return early if this element already has a plugin instance
       if (element.data('myplugin')) return;

       // pass options to plugin constructor
       var myplugin = new MyPlugin(this, options);

       // Store plugin object in this element's data
       element.data('myplugin', myplugin);
   });
};

There will be created new "MyPlugin" instance on each jQuery matching object.

How to change it (if it`s posible) so it would work on elements that are added in the future?

Thanks


Solution

  • I’ve been using live with success in my plugins often as a custom option. Here's a trivial example that adds an alert to elements that are clicked:

    $.fn.clickAlert = function(settings) {
        settings = $.extend({live: false}, settings);
    
        function clickAlertFn() {
            alert('Clicked!');
        }
    
        if (settings.live) {
            return this.live('click', clickAlertFn);
        } else {
            return this.click(clickAlertFn);
        }
    };
    
    // this will only work on existing `a` elements with class foo
    $('a.foo').clickAlert();
    
    // this will work on existing and future `a` elements with class bar
    $('a.bar').clickAlert({live: true});
    

    In this example anything that would work normally with $('...').live('click', ...') will work with $('...').clickAlert({live: true});

    One additional thing, most plugin designs have you do something like this:

    $.fn.foo = function() {
        return $(this).each(function() {
            // code in here...
        });
    }
    

    Unfortunately, using live inside the each loop won't work.