jQueryでtriggerされたイベントをjQueryを使わずに取得するための条件

  • 1
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

jQuery(elem).trigger(eventType)が実行されたとする。このとき発生したイベントをjQueryを利用せずに取得できるだろうか。

jQuery.fn.trigger()の実装の概要

jQuery.fn.trigger()jQuery.event.trigger()の薄いラッパーになっていて、処理の大半はjQuery.event.trigger()の中で行われる(どちらもsrc/event.jsで定義されている)。

現在のDOMではイベントを生成するAPI(new Event, document.createEvent)と、生成したイベントを発行するAPI(EventTarget.dispatchEvent(event))が提供されているが、jQueryはそれらのAPIを使わず、独自にイベントオブジェクトを作り、イベントのバブリング1なども自前で実装している。

jQuery.fn.trigger()によってイベントが発行される処理を大まかにまとめると次のようになる。

  1. イベントがバブリングするノードをリストアップして、それぞれに「jQueryから設定されたイベントハンドラを実行して、node['on' + type]が呼び出せそうならそれも実行する」という処理を行う。
    • ここでのtypetrigger()の引数として渡されたイベント名からネームスペースを取り除いたもの(jQuery(node).trigger("click.foo.bar")ならclickになる)。
    • type:が含まれている場合はnode['on' + type]は実行されない。
  2. イベントのpreventDefault()が呼ばれていなければ、elem[type]を見て、これが関数であれば実行する2
    • ここでのelemはイベントの起点になるノード(jQuery(elem).trigger(event))。
    • type:が含まれている場合はこの処理は実行されない。

  • click:
    1. バブリングの対象になるノードのonclickプロパティに関数を設定しておくと、1の処理の中で実行される。
    2. ほとんどのノードにはネイティブのclickメソッドがあるはずなので、イベント伝播の対象になるノードに標準のイベントリスナーを設定しておけば(伝播中に他のリスナーが伝播を抑止しない限り)イベントを取得できる。
  • click.foo.bar: clickと同じ。
  • reset:
    1. clickの1と同じ。
    2. イベントの起点になるノードにネイティブのresetメソッドがあるときにはclickの2と同じ。そうでない場合にはfoobarの2と同じ。
  • foobar(非標準のイベント)
    1. バブリングの対象になるノードのonfoobarプロパティに関数を設定しておくと、1の処理の中で実行される。
    2. イベントの起点になるノードのfoobarプロパティに関数を設定しておくと、2の処理の中で実行される。
  • ajax:success: 取得できない。

テスト: Catching jQuery events by vanilla JS - JSFiddle

参考・関連

CC0


  1. trigger()メソッド内のイベント伝播のシミュレートでは、capture phaseには対応せず、bubbling phaseのみ実装している。jQuery.fn.bindなどは、IE8以下ではcapture phaseがサポートされていないという理由でcapture phaseに対応していない(参考: Jquery .bind events triggered when event capture or event bubble(Stack Overflow)に対するT.J. Crowderの回答)のと関係があるのかもしれない。 

  2. 余談だが、一部のブラウザではHTMLElement.click()などで発火したイベントも伝播するので、ここでnode['on' + type]がもう一度実行される。