Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unbind an Anonymous Function

Can somebody tell how to "unbind" an anonymous function? JQUERY it's capable to do that, but how can I implement this Functionality in my own script.

This is the scenario:

The following code attach a 'onclick' event to the Div which have 'someDivId' as ID, now wen you click the DIV, it's show 'clicked!'.

var a  = document.getElementById('someDivId');
bindEvent(a,'click',function(){alert('clicked!');});

That's all great, the problem is how to "un-attach" the Function to the DIV if the function is anonymous or how to "un-attach" all attached events to the 'a' Element?

unBind(a,'click'); //Not necessarily the given params, it's just an example.

This is the code for bindEvent Method:

function bindEvent (el,evtType,fn){
    if ( el.attachEvent ) {
        el['e'+evtType+fn] = fn;
        el[evtType+fn] = function(){
            fn.call(el,window.event);
        }
        el.attachEvent( 'on'+evtType, el[evtType+fn] );
    } else {
        el.addEventListener( evtType, fn, false );
    }
}
like image 623
guzmanoj Avatar asked Apr 20 '12 22:04

guzmanoj


1 Answers

Finally, and after hours of Test&Errors i have found a solution, maybe it's not the best or most efficient but... IT WORKS! (Tested on IE9, Firefox 12, Chrome 18)

First all I'v create two cross-browser and auxiliary addEvent() and removeEvent() methods. (Idea taken from Jquery's source code!)

HELPERS.removeEvent = document.removeEventListener ?
function( type, handle,el ) {
    if ( el.removeEventListener ) {
    //W3C Standard    
    el.removeEventListener( type, handle, true );
    }
} : 
function( type, handle,el ) {
    if ( el.detachEvent ) {
        //The IE way
        el.detachEvent( 'on'+type, el[type+handle] );
        el[type+handle] = null;
    }
};

HELPERS.addEvent = document.addEventListener ?
function( type, handle,el ) {
    if ( el.addEventListener ) {
        //W3C Standard
        el.addEventListener( type, handle, true );
    }
} : 
function( type, handle,el ) {
    if ( el.attachEvent ) {
        //The IE way
        el['e'+type+handle] = handle;
        el[type+handle] = function(){
            handle.call(el,window.event);
        };
        el.attachEvent( 'on'+type, el[type+handle] );

    }
}

Also we need some kind of 'container' to store the attached events to elements, like this:

HELPERS.EVTS = {};

And finally the two callable and exposed to the users Methods: The next one to add an Event(event) and associate this Event to a Method (handler) for a specific Element (el).

    function bindEvent(event, handler,el) {

            if(!(el in HELPERS.EVT)) {
                // HELPERS.EVT stores references to nodes
                HELPERS.EVT[el] = {};
            }

            if(!(event in HELPERS.EVT[el])) {
                // each entry contains another entry for each event type
                HELPERS.EVT[el][event] = [];
            }
            // capture reference
            HELPERS.EVT[el][event].push([handler, true]);
            //Finally call the aux. Method
            HELPERS.addEvent(event,handler,el);

         return;

    }

Lastly the method that un-attach every pre-attached events (event) for an specific Element (el)

    function removeAllEvent(event,el) {

            if(el in HELPERS.EVT) {
                var handlers = HELPERS.EVT[el];
                if(event in handlers) {
                    var eventHandlers = handlers[event];
                    for(var i = eventHandlers.length; i--;) {
                        var handler = eventHandlers[i];
                        HELPERS.removeEvent(event,handler[0],el);

                    }
                }
            }   

    return;

    }

By the way, to call this methods you must do the following: Capture a DOM Node

    var a = document.getElementById('some_id');

Call the method 'bindEvent()' with the corresponding parameters.

    bindEvent('click',function(){alert('say hi');},a);

And to de-attach it:

    removeAllEvent('click',a);

That's all, hope will be useful for somebody one day.

like image 91
guzmanoj Avatar answered Sep 23 '22 20:09

guzmanoj