JavaScript
jQuery
イベント
Vanilla.JS

Vanilla JavaScriptでのイベント発火、ほか

More than 1 year has passed since last update.

JavaScriptで書いていた複雑な部分をフレームワークで運用する形としていくと、jQueryの必要性がどんどん減ってきます。そこで、既存のjQueryコードもVanilla JSで書き直すこととしていったのですが、イベント処理まわりではjQueryに慣れた観点からすれば、意外なことが多かったです。

なお、「イベントをaddEventListenerでセットする」というのは、当たり前すぎるので省略します。

「イベントハンドラ」と「デフォルト処理」の区別

jQueryの場合、.focus()とすれば「フォーカスを当てる処理」と「イベントハンドラ」の両方が動きます。それに対して、JavaScriptでは、この2つの操作は別個に行う必要があります(ただし、.click()だけは例外で、実際にクリックしたときと同様に「イベントハンドラ」→「クリックしたことによる動作」と進んでいきます)。

まずはシンプルなデフォルト処理の方を考えますが、実を言えば「デフォルトで何かが起きる」イベントはそんなに多くありません。jQueryにあるようなもので言えば、clickfocusblursubmit程度です。

イベントハンドラを動かす方法

コードからイベントハンドラを動かしたい場合、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 = falsepreventDefault不可)」のイベントとなります。バブリングやpreventDefaultを使いたい場合は、第2引数に指定してnew Event('イベント名', {bubbles: true, cancelable: true})のような指定が必要となります。

イベントの配信

イベントオブジェクトができたら、あとは配信です。element.dispatchEvent(ev)のようにすることで、イベントが動き始めます。

もちろん手動で起こしたイベントにデフォルト操作は存在しませんが、dispatchEventの返り値は「イベント中でpreventDefaultされればfalse、されなければtrue」なので、自作のイベントでも後続処理をどうするかの制御にpreventDefaultを使うことができます。