5

有人可以告诉如何“取消绑定”匿名函数吗?JQUERY 可以做到这一点,但是我如何在我自己的脚本中实现这个功能。

这是场景:

以下代码将“onclick”事件附加到以“someDivId”为 ID 的 Div,现在当您单击 DIV 时,它会显示“已单击!”。

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

太好了,问题是如果函数是匿名的,如何将函数“取消附加”到 DIV,或者如何将所有附加事件“取消附加”到“a”元素?

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

这是 bindEvent 方法的代码:

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 );
    }
}
4

5 回答 5

4

最后,经过数小时的测试和错误,我找到了一个解决方案,也许它不是最好的或最有效的,但是......它有效!(在 IE9、Firefox 12、Chrome 18 上测试)

首先,我创建了两个跨浏览器和辅助 addEvent() 和 removeEvent() 方法。(想法取自 Jquery 的源代码!)

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] );

    }
}

我们还需要某种“容器”来将附加的事件存储到元素中,如下所示:

HELPERS.EVTS = {};

最后是两个可调用并向用户公开的方法:下一个添加事件(事件)并将此事件与特定元素(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;

    }

最后,取消附加特定元素(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;

    }

顺便说一句,要调用此方法,您必须执行以下操作: 捕获 DOM 节点

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

使用相应的参数调用方法“bindEvent()”。

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

并卸下它:

    removeAllEvent('click',a);

就是这样,希望有一天对某人有用。

于 2012-04-21T13:50:29.263 回答
2

就个人而言(我知道这不是“最好的”方式,因为它确实需要我思考我在做什么),我喜欢只使用on*我正在使用的元素的事件属性。

这具有能够快速轻松地分离事件的便利优势。

var a = document.getElementById('someDivId');
a.onclick = function() {alert("Clicked!");};
// later...
a.onclick = null;

但是,您必须小心这一点,因为如果您尝试添加第二个事件处理程序,它将覆盖第一个。记住这一点,你应该一切都好。

于 2012-04-20T22:40:26.477 回答
1

我不确定您是否可以取消绑定通过 javascript 附加的匿名函数。如果可能,您可以简单地从 DOM 中删除元素并重新创建它。这将摆脱以前附加的任何事件处理程序。

于 2012-04-20T22:59:05.287 回答
1

JavaScript 不提供附加到节点的事件侦听器列表。

您可以删除节点的所有事件侦听器,但使用该Node.cloneNode方法,请参见此处:https ://developer.mozilla.org/En/DOM/Node.cloneNode

这会克隆节点(显然),但不会克隆附加到它的事件侦听器。

您也可以将空函数绑定为事件侦听器:

function noop() {}
bindEvent(myElement, "click", noop);
于 2012-04-20T23:34:58.867 回答
-1

这是来自 jquery 的来源

jQuery.removeEvent = document.removeEventListener ?
    function( elem, type, handle ) {
        if ( elem.removeEventListener ) {
            elem.removeEventListener( type, handle, false );
        }
    } :
    function( elem, type, handle ) {
        if ( elem.detachEvent ) {
            elem.detachEvent( "on" + type, handle );
        }
    };
于 2012-04-20T22:52:34.103 回答