web-dev-qa-db-ja.com

jQuery:同じイベントの複数のハンドラー

2つのイベントハンドラーを同じ要素の同じイベントにバインドするとどうなりますか?

例えば:

var elem = $("...")
elem.click(...);
elem.click(...);

最後のハンドラーが「勝ち」ますか、それとも両方のハンドラーが実行されますか?

134
flybywire

両方のハンドラーが実行され、jQueryイベントモデルは1つの要素で複数のハンドラーを許可するため、後のハンドラーは古いハンドラーをオーバーライドしません。

ハンドラーはバインドされた順序で実行されます

162
Russ Cam

fgの2つのハンドラーがあり、それらが既知の固定された順序で実行されることを確認してから、それらをカプセル化する場合:

$("...").click(function(event){
  f(event);
  g(event);
});

このように(jQueryの観点から)oneハンドラーのみがあり、指定された順序でfおよびgを呼び出します。

36
Stephan202

jQueryの.bind()はバインドされた順序で起動します

イベントが要素に到達すると、その要素のそのイベントタイプにバインドされているすべてのハンドラーが起動されます。複数のハンドラーが登録されている場合、それらは常にバインドされた順序で実行されます。すべてのハンドラーが実行された後、イベントは通常のイベント伝搬パスに沿って継続します。

ソース: http://api.jquery.com/bind/

JQueryの他の関数(例:.click())は.bind('click', handler)のショートカットであるため、バインドされた順序でもトリガーされると思います。

17
allicarn

連鎖を使用して、イベントを順番に実行できる必要があります。例:

$('#target')
  .bind('click',function(event) {
    alert('Hello!');
  })
  .bind('click',function(event) {
    alert('Hello again!');
  })
  .bind('click',function(event) {
    alert('Hello yet again!');
  });

私は以下のコードが同じことをしていると思います

$('#target')
      .click(function(event) {
        alert('Hello!');
      })
      .click(function(event) {
        alert('Hello again!');
      })
      .click(function(event) {
        alert('Hello yet again!');
      });

ソース: http://www.peachpit.com/articles/article.aspx?p=1371947&seqNum=

TFM も言います:

イベントが要素に到達すると、その要素のそのイベントタイプにバインドされているすべてのハンドラーが起動されます。複数のハンドラーが登録されている場合、それらは常にバインドされた順序で実行されます。すべてのハンドラーが実行された後、イベントは通常のイベント伝搬パスに沿って継続します。

10
anddoutoi

両方のハンドラーが呼び出されます。

インラインイベントバインディング (例:"onclick=...")を考えているかもしれませんが、大きな欠点はイベントに対して1つのハンドラーしか設定できないことです。

jQueryは DOMレベル2イベント登録モデル に準拠しています:

DOMイベントモデルを使用すると、単一のEventTargetに複数のイベントリスナーを登録できます。これを実現するために、イベントリスナーは属性値として保存されなくなりました

2
Crescent Fresh

Stephan202のカプセル化と複数のイベントリスナーの2つの方法を使用して、正常に動作するようにしました。 3つの検索タブがあります。入力テキストIDを配列で定義しましょう。

var ids = new Array("searchtab1", "searchtab2", "searchtab3");

Searchtab1の内容が変更された場合、searchtab2とsearchtab3を更新します。カプセル化のためにこのようにしました:

for (var i in ids) {
    $("#" + ids[i]).change(function() {
        for (var j in ids) {
            if (this != ids[j]) {
                $("#" + ids[j]).val($(this).val());
            }
        }
    });
}

複数のイベントリスナー:

for (var i in ids) {
    for (var j in ids) {
        if (ids[i] != ids[j]) {
            $("#" + ids[i]).change(function() {
                $("#" + ids[j]).val($(this).val());
            });
        }
    }
}

私は両方の方法が好きですが、プログラマーはカプセル化を選択しましたが、複数のイベントリスナーも機能しました。 Chromeを使用してテストしました。

2
GeneralElektrix

1つのハンドラーが次から次へと発生することを保証する回避策があります。2番目のハンドラーを含む要素にアタッチし、イベントをバブルアップさせます。コンテナにアタッチされたハンドラーで、event.targetを見て、それが目的のものであれば何かを行うことができます。

おそらく粗野ですが、間違いなく機能するはずです。

1
David

jqueryは複数のイベントハンドラーを許可するため、両方のハンドラーを実行します。サンプルコードを作成しました。あなたはそれを試すことができます

デモ

0
Vikram Rajput