jQuery離れを進めようと、少しずつ既存コードをネイティブDOMで書き直しているような箇所もあったりする1のですが、混在すると特有なトラブルに見舞われたりもします。
TL; DR
- jQueryの
.triggerで起きるのは、「jQuery上のイベント」、「on***」、「(起こせるものは)標準操作」だけ -
addEventListenerでセットしたイベントを駆動させることはない - ただ、
clickでは「標準操作」がイベントも引き起こす
発生した問題
jQueryで書いていたものを徐々に切り替えていたのですが、jQueryでtriggerしたはずのイベントが、addEventListenerで拾えない、ということが発生しました。
jQueryのイベントシステム
jQuery 1.0が出た頃は、ブラウザのDOMへの対応状況も、現代から見ればめちゃくちゃと言っていい状況でした。そんな中でバブリングなどをきちんと実現するために、jQueryはイベントシステムを自前で構築しています。これは、最新版の3系列でも同じ状況です。
そして、triggerのコードを追いかけてみたところ、以下のような動作になっていました。
- DOMの仕様のように、DOMツリーの上からたどって目的の要素を抽出して2、そこについているjQueryイベントと
on***を実行していく - ターゲットから上位に戻っていって、引き続きイベントを実行していく
-
.preventDefault()されていなかった場合、(存在すれば)ネイティブな動作をさせるメソッド(focus()、click()、submit()など少数派です)を実行する
ということで、addEventListenerでセットされたものを呼ぶのに必要なdispatchEventなどは、どこにもありませんでした。なお、ネイティブのclick()だけは例外的に、「イベントも実行する」メソッドになっていますので、これだけは実行されます。
結論
jQueryのイベントはjQueryでしか受けられないので、カスタムイベントで状態の受け渡しをする系を作っているような場合は、先にイベントをtriggerする側をネイティブに切り替えないと、イベントを拾えなくなります。なお、jQueryもネイティブのaddEventListenerでイベントを拾っていますので、逆に「ネイティブDOMでdispatchEventしたイベントをjQueryのハンドラで拾う」ことは、問題なく可能です。