3

I need some design advice on how to clean up my plugin when it is destroyed.

I listen for blur events on the window, but am not sure how to remove those events when the plugin is destroyed. If the plugin is applied to multiple elements, but only destroyed for one element, it should still work for other elements. What would be the right way to design this?

(function( $ ) {

    var methods = 
    {
        init : function( options ) {
            var that = this;

            $(window).blur( function( e ) {
                that.css( "color", "red" );
                console.log( "still here" );
            });
        },

        destroy : function( ) {
            console.log( "hmmm, got to take out that blur" );
        }
    };

    $.fn.pleaseKillMe = function( method )
    {
        if ( methods[method] ) {
            return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
        }
        else if ( typeof method === 'object' || ! method ) {
            return methods.init.apply( this, arguments );
        }
        else {
            $.error( 'Method ' +  method + ' does not exist on jQuery.p5shrinkwrap' );
        }
    };

})( jQuery );

3 Answers 3

6

Your question illustrates why it is better to use .on() and .off(), than it is to use .blur() when binding event handler functions. AFAIK, it's not possible to unbind the unique event handler when you use .blur().

Here's what you can use:

$(window).on('blur.handlerID', function() {
    //do something event handling
});

$(window).off('blur.handlerID');

Where handlerID is a literal string that uniquely identifies your event handler.

jQuery .off() documentation

8
  • This will unbind all blur events for window, not specific to plugin
    – A. Wolff
    Commented Jan 25, 2013 at 22:02
  • 1
    In the OPs example, there's only one window blur event handler. But I've updated my answer to account for multiple event binds.
    – Elliot B.
    Commented Jan 25, 2013 at 22:03
  • @ElliotB. Too fast for me ;) Commented Jan 25, 2013 at 22:07
  • and how to generate a unique handlerID for each element that gets this plugin? is there a best practice for that?
    – jedierikb
    Commented Jan 25, 2013 at 22:08
  • If you know concretely how many event handlers you're going to create, then you can name it anything you want. If the number of event handlers is dynamic, then you can inject some sort of count variable: ` Your question illustrates why it's better to use .on() and .off(), than it is to use .blur() when binding events. AFAIK it's not possible to unbind the unique event handler when you use .blur(). Here's what you can use: $(window).off('blur.'+i); where i is 1, 2, 3 or 4 etc.
    – Elliot B.
    Commented Jan 25, 2013 at 22:11
3

I have something similar in a framework I developed. Except I was removing event handling for part of a screen saver. Anywho, back on point. You should name your events (that is what I did), like this:

$(window).bind("blur.SomeIdentifier", function () {//pre 1.7
$(window).on("blur.SomeIdentifier", function () {//1.7+
 //....
});

and now later, you may remove that exact event on destroy:

$(window).unbind("blur.SomeIdentifier");//pre 1.7
$(window).off("blur.SomeIdentifier");//1.7+
0

Use $(window).off('click.yourAppName', method);. For the off method to take effect you have to have assigned the listener with the on method. The .yourAppName in there is a namespace and need to be the same in the call to on. This is to keep your plugin events from interfering with other events within the same app.

Not the answer you're looking for? Browse other questions tagged or ask your own question.