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のハンドラで拾う」ことは、問題なく可能です。