6
4

More than 3 years have passed since last update.

preventDefault, stopPropagation, stopImmediatePropagationまとめ

Posted at

はじめに

Javascriptでアプリ開発していると、なんとなく"予防的"に、preventDefaultstopImmediatePropagationをコード中で併記する変な癖がついてしまっていました。(違いは理解しているつもりだったのですが、IME関連の処理を書いている時からpreventDefaultが効かなくなったりして混乱してしまったみたい。)

確認用として、これらでキャンセルできるイベントについて整理します。

テスト条件

次のようなHTMLで、contentEditableな要素を含むアプリを想定します。

<html>
<body>
<div id="div0" contentEditable="true">入力欄</div>
</body>
</html>

このHTMLに対して、Javascriptでは次のイベントリスナーを登録しておきます。

const div0 = document.getElementById("div0");
div0.addEventListener("keydown", OnKeydown1, false);
div0.addEventListener("keydown", OnKeydown2, false);
div0.addEventListener("input", OnInput, false);
div0.addEventListener("keyup", OnKeyup, false);
window.addEventListener("keydown", OnKeydownWin, false);
window.addEventListener("keyup", OnKeyupWin, false);

addEventListenerの登録順序も表記の順とします。

さて、これを実行し、要素div0の中でキー入力を行うと、次の順でイベントが発火します。

  1. OnKeydown1
  2. OnKeydown2
  3. OnKeydownWin
  4. OnInput
  5. OnKeyup
  6. OnKeyupWin

これがデフォルトの状況となります。OnKeydownWinとOnKeyupWinはバブリングにあたります。

発火を抑制できるイベント

上記の条件下において、OnKeydown1 イベントの中でpreventDefaultstopPropagationstopImmediatePropagationのいずれかをcallした場合、2~6のイベントでキャンセルされるものを以下の表記に記載します。×印のついたイベントはキャンセルされ、なにも記述の場合は発火することを意味します。

イベント名 preventDefault stopPropagation stopImmediatePropagation
OnKeydown2 ×
OnKeydownWin × ×
OnInput ×
OnKeyup
OnKeyupWin

preventDefaultstopPropagationもしくはstopImmediatePropagationを併記した場合は、どちらかで×印が付いているイベントはキャンセルされます。

簡単に挙動を纏めると、次のようになります。preventDefaultでキャンセルできるのはデフォルト処理であり、今回のcontentEditableな要素に対してのキー入力では、文字入力がキャンセルされます。よってOnInputがキャンセルされます。 一方で、もう一つ登録されたOnkeydown2やバブリングであるOnkeydownWinはキャンセルされずに発火します。また、OnKeyupはkeydownとは独立したイベントとみなされ、キャンセルできません。

stopPropagationはバブリングだけをキャンセルします。よって、OnkeydownWinがキャンセルされます。しかし、 Onkeydown2は同じ要素の同じイベントに登録されたリスナーであってバブリングではないのでキャンセルできません。

Onkeydown2もキャンセルしたい場合にはstopImmediatePropagationを使います。これはバブリングに加えて、同じ要素の同じイベントに続けて登録されたリスナーもキャンセルします。

例外

IME制御は上記が当てはまらない場合があります。詳しくは以前のまとめへ

さいごに

まとめて思うのは、OnKeydown2だけをキャンセルして、バブルリングのOnKeydownWinは発火させることはできないのだろうか。私の場合は、それがやりたかった為に無意識にコードをこじらせている部分があります。。。

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4