5

誰かが無名関数を「バインド解除」する方法を教えてもらえますか?JQUERYはそれを行うことができますが、この機能を自分のスクリプトに実装するにはどうすればよいですか。

これがシナリオです:

次のコードは、IDとして「someDivId」を持つDivに「onclick」イベントをアタッチします。DIVをクリックすると、「clicked!」と表示されます。

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でテスト済み)

まず、2 つのクロスブラウザーと補助的な 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 = {};

最後に、呼び出し可能でユーザーに公開される 2 つのメソッド: イベント (event) を追加し、このイベントを特定の要素 (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;

ただし、2番目のイベントハンドラーを追加しようとすると、最初のイベントハンドラーが上書きされるため、これには注意する必要があります。それを覚えておいてください、そうすればあなたはすべて元気になるはずです。

于 2012-04-20T22:40:26.477 に答える
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

JavaScript 経由でアタッチされた無名関数のバインドを解除できるかどうかはわかりません。可能であれば、要素を DOM から単純に削除して再作成することができます。これにより、以前にアタッチされたすべてのイベント ハンドラーが削除されます。

于 2012-04-20T22:59:05.287 に答える
-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 に答える