2011-02-07 15 views
28

jQueryに「グローバル」アンバインド機能があります。そのため、特定の名前空間からすべてのバインドされたイベントを削除できますか?例:特定の名前空間からすべてのjQueryイベントをどのようにアンバインドしますか?

// assume these are the events bound to different elements 
$('#foo').bind('click.myNS', ...); 
$('#bar').bind('keyup.myNS', ...); 
$('#baz').bind('dblclick.myNS', ...);  

// magic occurs here... 
$.magicalGlobalUnbindFunction('.myNS'); 

// ...and afterwards, the three binds from above are gone 

アンバインドで見たすべての例では、最初にいくつかの要素を選択する必要があります。私は技術的には$('*').unbind('.myNS')を行うことができると思うが、それはのように非常にとは思えない。

+0

のようになります。私は、イベントがバインドしているものである、HTMLは名前空間を持っているとは思いません。 – jondavidjohn

+0

@jondavidjohn:この形式の名前空間は、jQueryによって提供されるものです。http://api.jquery.com/bind/これは、他の誰かに影響を与えることなく簡単にバインド解除できるように、イベントハンドラを整理する単なる方法です。プラグイン)。 –

+0

@jondavidjohn:いいえ、jqueryを使用すると、イベントに独自の名前空間を付けることができます。したがって、ここでの質問は、「x名前空間のすべてのバインドされたイベントを選択するjqueryの方法はありますか?」 –

答えて

13

イベントをバインド解除する各要素に、クラスとしてmyNSを追加できます。

+0

これは、彼が言うことは「非常に非効率的」だと思うのです。 – user120242

+0

@ user120242:いいえ、セレクタとして*を使用すると、ページ上のすべての要素から基本的にイベントを探してバインドを解除しようとするため、非効率です。 mikerobiが提案していることは、バインディング時に、特定のクラス名を要素に追加し、その後、そのクラス名をセレクタとして使用して、関連する要素のみを選択することです。 –

+0

IMOこれはおそらく最良の解決策です... jqueryには既に何か他のものが組み込まれていないと仮定しています...内部的には名前空間のリストを保持しています...公式のセレクタがない場合でも「このイベント名前空間を持つすべての要素を選択する」と言うと、理論的にはこれを行うためのjqueryプラグインを作成するのに十分なはずです。 –

4

本当にあなたは魔法の世界的な機能を探していますが、いつものように幻想は、この場合はシンプルさの幻想しか得られません。

.live()または.delegate()(これはlive()の唯一の変形です)を使用するjQueryソリューションもあります。

$("body").delegate("#foo", "click.myNs", func)を使用すると、イベントをバインドし、$("#body").undelegate(".myNs")を使用してバインド解除します。私はここで "ボディ"要素を使用しますが、あなたがバインドする必要があるすべての要素の祖先である任意の要素を使用することができます。

これにより、「バインド解除」作業が速くなりますが、再度イベントが遅くなります。 #foo#bar#etcはすべて同じ要素またはそれらの小さなセットされている場合

0

あなたがバインド機能

$('#foo').bind('click.myNS', ...).addClass('removeLater'); 
$('#bar').bind('keyup.myNS', ...).addClass('removeLater'); 
$('#baz').bind('dblclick.myNS', ...).addClass('removeLater'); 

、その後

$('.removeLater').unbind(); 

内のクラスを追加する必要があり、あなたも行うことができます:

$('div, button').unbind(); 

iあなたはそれはあなたがjQueryの内部に侵入する必要があります良いアイデア

3

ではないでしょう削除したくないバインドされたイベントを持っているfは、ここでは簡単な実装の作業のデモです:

http://jsfiddle.net/nkMQv/1/

主な作業は通常のjsループで行われ、このページでも最終的にループするのはわずか106項目しかないため、非常に非効率的であってはいけません。もちろん、jQueryハンドラコレクション内のアイテムの量を可能な限り小さく保つために、できるだけイベント委譲を使用する必要があります。

+0

+1しかし、確かに汚いです。 – fncomp

+0

はい、ハンドラーの名前空間は残念ながらキャッシュオブジェクトの深いところに格納されています。そのため、内部ルーピングとtmp変数があまりにも多くあります:(しかし、それを隠してパブリックメソッドのみを使用すると、汚れがわかりません – Esailija

+0

私はあなたのテクニックについても考えていましたが、私たちのソリューションの間の実際の違いは、私の場合、より多くの処理能力を必要とするスペースが必要だと思っています。 – fncomp

9

あなたは常に$ .fn.bindをラップして、必要に応じて参照文献キャッシュできます

(function ($) { 
    var origBind = $.fn.bind, 
     boundHash = {}; 

    $.fn.bind = function (type, data, fn) { 
     var namespace = '', 
      events = []; 

     if (typeof type === 'string') { 
      // @todo check the allowed chars for event namespaces. 
      namespace = type.replace(/^[^.]+/, ''); 

      if (namespace.length) { 
       events = boundHash[namespace]; 

       // Namespaces can hold any number of events. 
       events = boundHash[namespace] = $.isArray(events) ? events : []; 

       // Only really need ref to the html element(s)  
       events.push({ 
        type: type, 
        fn: $.isFunction(fn) ? fn : data, 
        that: this.length > 1 ? this.toArray() : this[0] 
       }); 
      } 
     } 

     origBind.apply(this, arguments); 
    }; 

    // namespace to be muffled. Feel free to qualify a specific event type. 
    $.muffle = function (namespace, type) { 
     var events = []; 

     if (boundHash.hasOwnProperty(namespace)) { 
      events = boundHash[namespace]; 

      $.map(events, function (event) { 
       var _type = type || event.type; 

       if (event.type.indexOf(_type) === 0) { 
        $(event.that).unbind(_type, event.fn); 
       } 
      }); 

      // @todo think of better return value. 
      return true; 
     } 

     // @todo think of better return value. 
     return false 
    }; 
})(jQuery); 
+0

'.data'でも同じことができます。 – fncomp

+0

ニース。これは本当に良いです。ありがとう! – CambridgeMike

+0

私はリポジトリを削除したので、関連するコメントは削除されました。 – fncomp

0

を使用すると、その後のjQueryのbindメソッドをオーバーライドして、可能性があり、オーバーライド・ストア内のすべての名前空間の参照と関連するイベントを連想配列に格納し、バインドを解除する名前空間イベントに基づいて配列にアクセスします。コードは次のようなものになる可能性があります。

var eventArray=[]; 
(function ($) { 
    var bind = $.fn.bind; 
    $.fn.bind= function() { 
    var result = bind.apply(this, arguments); 
    var selector=arguments[0]; 
    var nameSpace= selector.split(".")[1]; //code to select the nameSpace eg. click.myNS o/p->myNS (update this if your selector has multiple '.') 
    if(!eventArray[nameSpace]) //if the associative array does not contain the namespace yet 
    { 
     eventArray[nameSpace]=[]; 
    } 
    eventArray[nameSpace].push(selector); 
    return result; 
}; 
})(jQuery); 

ここで、必要に応じてイベントの配列を解除することができます。名前空間myNSのすべてのイベントをアンバインドするコードは、次のようになります。

$.each(eventArray['myNS'],function(){ 
    $(this).unbind(); 
}); 

これは良い解決策です。何か間違いがあった場合は教えてください。

4

jQueryのOnOffメソッドを使用する必要があります。ドキュメントをセレクタとして使用します。

$(document).off('.myNS'); 

$(document).on('click.myNS','#foo', ...); 
$(document).on('keyup.myNS','#bar', ...); 
$(document).on('dblclick.myNS','#baz','''); 

、あなたの方法は

$(document).on('click.myNS','#foo', fooClicked); 
var fooClicked = function(e){ 
    var $this = $(e.target); 
    // do stuff 
} 
関連する問題