DOMオブジェクトには昔からdispatchEventとか,addEventListenerとかあって,最近だと,node.jsのEventEmitterとか,jQueryのon, triggerを使って自作のオブジェクト間でアプリケーション的に定義されたイベントをやりとりできる.
これまで,自作オブジェクトからイベントを発行するのに,jQueryのtriggerを使ってたけど,意図しない挙動をすることがあることが分かって,triggerHandlerを使うように変えた.
jQuery.trigger()は,イベントタイプと一致する関数をレシーバが持ってるとき,その関数が呼ばれる.
イベントのやりとりと,メソッドの呼び出しは独立しているというイメージがあったので,うっかり同名のメソッドを定義したときに,一見するとよく分からない挙動になって,難しい.
なので,自作オブジェクトがイベントを発行するときは,triggerではなく,triggerHandlerを使うほうがよいと思う.
例
var a = {hi: function(){console.log('hi!!!') }}; $(a).trigger('hi');
これはhi!!!出る.
var a = {hi: function(){console.log('hi!!!') }}; $(a).triggerHandler('hi');
これはhi!!!出ない.
参照
リファレンス見たら書いてある.
Note: For both plain objects and DOM objects other than window, if a triggered event name matches the name of a property on the object, jQuery will attempt to invoke the property as a method if no event handler calls event.preventDefault(). If this behavior is not desired, use .triggerHandler() instead.
.trigger() | jQuery API Documentation
triggerHandlerは最初の1件だけに適用されるので気をつける必要もある.
While .trigger() will operate on all elements matched by the jQuery object, .triggerHandler() only affects the first matched element.
.triggerHandler() | jQuery API Documentation
雑談(1)
jQueryでググると上のほうにjQuery 日本語リファレンスっていうのも出てくるけど,2010年から更新されていない.twitterの@semoohさんのアカウントも更新されてないし不穏な感じがする.本家のリファレンスを読むべき.
雑談(2)
jQueryのtrigger, on挙動が怪しい感じで,DOMオブジェクトに対して使うときは良いけど,自作のオブジェクトに対して使うときは,このように微妙な挙動があるので,何か別のライブラリを使うほうが良いかもしれない.
雑談(3)
同名のプロパティに関数が入ってたらそれが呼ばれるの,どういうとき便利なのか分からない.こういうとき便利とか,こういう観点では妥当な仕様であるとか,なんか知見ある人いたら教えてください.
会話
先週くらいに気付いて会話してた.
12:31 hitode909 var a = {hi: function(){console.log('hi!!!') }}; $(a).trigger('hi')
12:32 hitode909 これでhi()呼ばれるの知らなかった
12:32 aereal え
12:32 hitode909 var a = {hi: function(){console.log('hi!!!') }}; $(a).triggerHandler('hi')
12:32 hitode909 これだと呼ばれない
12:32 hitode909 http://api.jquery.com/trigger/
12:32 hitode909 Note: For both plain objects and DOM objects other than window, if a triggered event name matches the name of a property on the object, jQuery will attempt to invoke the property as a method if no event handler calls event.preventDefault(). If this behavior is not desired, use .triggerHandler() instead.
12:33 hitode909 The .trigger() method can be used on jQuery collections that wrap plain JavaScript objects similar to a pub/sub mechanism; any event handlers bound to the object will be called when the event is triggered.
12:33 aereal ほえ〜〜〜
12:33 aereal パブサブ
12:33 aereal 知らなかった
12:33 hitode909 ハブバブ
12:34 hitode909 reset()呼ばれたら
12:34 hitode909 $(this).trigger('reset') とかしてたら
12:34 hitode909 無限にtriggerされてやばかった
12:34 aereal やばい
12:34 aereal 単にイベントを発生させたいときは triggerHandler を使えってことかなるほど〜〜〜
12:35 hitode909 これまでは名前が被ってないだけでうまく動いていたのであった
12:35 aereal 逆に click みたいなプロパティがあると
12:35 aereal それが呼ばれる?????
12:35 hitode909 便利そう??????
12:36 aereal 呼ばれた
12:36 aereal 便利???????
12:36 hitode909 trigger('click')したいとき,たぶんDOMオブジェクトに対してtriggerするから,あまりうれしくない気がする??
12:38 hitode909 あとtriggerは全要素に対して実行されるけどtriggerHandlerは最初の1つにだけ行われるので微妙に直交してない
12:38 aereal なるほど……