jQuery: Unbind event handlers to bind them again later

Solution 1:

There is a events element in the data of the item. This should get your started, you can read your elements and store the handlers in an array before unbinding. Comment if you need more help. I got this idea from reading the $.fn.clone method so take a look at that as well.

$(document).ready(function() {
    $('#test').click(function(e) {
        alert('test');
        var events = $('#test').data("events");
        $('#test').unbind('click', events.click[0]);
    });
});

<a id="test">test</a>

Solution 2:

Here is how to achieve that, provides a storeEvents and a restoreEvents methods on a selection. storeEvents takes a snapshot of the events on the moment it is called. restoreEvents restores to the last previous snapshot. Might need to twist it a little for parameterizing the unbinding while restoring, maybe you'd like to keep the bound events after the last snapshot.

(function($){

    function obj_copy(obj){
            var out = {};
        for (i in obj) {
            if (typeof obj[i] == 'object') {
                out[i] = this.copy(obj[i]);
            }
            else
                out[i] = obj[i];
        }
        return out;
    }


    $.fn.extend({

        storeEvents:function(){
            this.each(function(){
                $.data(this,'storedEvents',obj_copy($(this).data('events')));
            });
            return this;
        },

        restoreEvents:function(){
            this.each(function(){
                var events = $.data(this,'storedEvents');
                if (events){
                    $(this).unbind();
                    for (var type in events){
                        for (var handler in events[type]){
                            $.event.add(
                                this, 
                                type, 
                                events[type][handler], 
                                events[type][handler].data);
                        }
                    }
                }
            });
            return this;
        }

    });
})(jQuery);

Solution 3:

Since jQuery 1.4.2+ changes how event handlers are stored, this seems relevant:

The best way I found was to use event namespacing:

var ary_handlers = [ fn_highlight, fn_onpress, fn_cleanup ];
for ( idx = 0; idx < ary_handlers.length; idx++ ){
  $('#test').bind('click.foobar',ary_handlers[idx]);
}

// and then later: 
$('#test').unbind('.foobar');  

In the above example, all foobar events unbound. Notice that if you needed finer grain control, you could namespace each click handler and correlate to your array of handlers:

var ary_handlers = [ fn_highlight, fn_onpress, fn_cleanup ];
for ( idx = 0; idx < ary_handlers.length; idx++ ){
  $('#test').bind('click.ns_' + String(idx), ary_handlers[idx]);
}

// and then later you could pick off a specific one to unbind
$('#test').unbind('.ns_2');

Solution 4:

There is a jQuery plugin called Copy Events, which copies events from one object to another. This could very easily be used to "save" events from one element and bring them back later. Just one more option :)

Edit: fixed broken link