JavaScriptで書いていた複雑な部分をフレームワークで運用する形としていくと、jQueryの必要性がどんどん減ってきます。そこで、既存のjQueryコードもVanilla JSで書き直すこととしていったのですが、イベント処理まわりではjQueryに慣れた観点からすれば、意外なことが多かったです。
なお、「イベントをaddEventListener
でセットする」というのは、当たり前すぎるので省略します。
「イベントハンドラ」と「デフォルト処理」の区別
jQueryの場合、.focus()
とすれば「フォーカスを当てる処理」と「イベントハンドラ」の両方が動きます。それに対して、JavaScriptでは、この2つの操作は別個に行う必要があります(ただし、.click()
だけは例外で、実際にクリックしたときと同様に「イベントハンドラ」→「クリックしたことによる動作」と進んでいきます)。
まずはシンプルなデフォルト処理の方を考えますが、実を言えば「デフォルトで何かが起きる」イベントはそんなに多くありません。jQueryにあるようなもので言えば、click
、focus
、blur
、submit
程度です。
イベントハンドラを動かす方法
コードからイベントハンドラを動かしたい場合、jQueryでは.trigger
だけで済みますが、本来のJavaScriptでは「イベントの作成」と「イベントの送信」という2つのプロセスを経なければいけません。
イベントの作成
最初に注意事項ですが、マウスやキーボードのイベントでは、専用のイベントオブジェクトが本来は存在して、マウスの座標や押されたキーなどを送信しています。keydown
などの名前で汎用のイベントを作成した場合にもイベントハンドラが動くことは動きますが、それらの追加データはもちろん存在しませんので、データが必要なハンドラの場合はエラーとなります。target
などはすべてのイベントオブジェクトに共通しますので、汎用のものでも問題なく動作します。
まずは、IE 9でも使えるやり方から紹介します。こちらではcreate
してからinit
する必要があります。
// 汎用のイベントを作成
var ev = document.createEvent('HTMLEvents');
// 初期化
// bubbles: バブリングするかどうか
// cancelable:イベントのデフォルトをキャンセルできるかどうか
ev.initEvent('イベント名', bubbles, cancelable);
最近のブラウザ(IEは11でもアウト)では、Event
がコンストラクタとなっていて、そのままnew Event
一発で済むようになっています。ただし、new Event('イベント名')
とだけしてしまうと、「bubbles = false
(バブリングしない)、cancelable = false
(preventDefault
不可)」のイベントとなります。バブリングやpreventDefault
を使いたい場合は、第2引数に指定してnew Event('イベント名', {bubbles: true, cancelable: true})
のような指定が必要となります。
イベントの配信
イベントオブジェクトができたら、あとは配信です。element.dispatchEvent(ev)
のようにすることで、イベントが動き始めます。
もちろん手動で起こしたイベントにデフォルト操作は存在しませんが、dispatchEvent
の返り値は「イベント中でpreventDefault
されればfalse
、されなければtrue
」なので、自作のイベントでも後続処理をどうするかの制御にpreventDefault
を使うことができます。