【JavaScript】イベントの中止 - preventDefault / stopPropagation / stopImmediatePropagation
JavaScriptのブラウザイベントにおけるイベントの中止について解説します。
検証環境
イベントの中止
Eventオブジェクトにはイベントを中止するメソッドが備わっています。
リンクの規定動作を中止するメソッドやイベントの伝搬を中止するメソッドなど種類があります。
このドキュメントでは次の3つのメソッドについて解説します。
- preventDefault
- stopPropagation
- stopImmediatePropagation
規定動作の中止(preventDefault)
規定動作の中止にはpreventDefaultメソッドを使用します。
規定動作とは例えばリンクのページ遷移やチェックボックスのチェックです。
基本構文
Eventオブジェクト.preventDefault()
サンプル
<style>
#log {
border: 1px solid black;
padding: 5px;
}
</style>
<main id="main">
<div id="div">
<input id="checkbox" type="checkbox">
<a id="link" href="https://it-hack.net/">TOPページ</a>
</div>
</main>
<pre id="log"></pre>
<button id="btn">リセット</button>
<script type="text/javascript">
function logger( text ) {
let log = document.getElementById('log');
log.textContent += text + "\n";
}
function reset( event ) {
let log = document.getElementById('log');
log.textContent = "";
}
let btn = document.getElementById('btn');
btn.addEventListener('click', reset);
let main = document.getElementById('main');
main.addEventListener('click', function() {
logger("Main Event.");
});
let div = document.getElementById('div');
div.addEventListener('click', function() {
logger("Div Event.");
});
let checkbox = document.getElementById('checkbox');
checkbox.addEventListener('click', function( event ) {
logger("Checkbox Event.");
___ih_hl_start
event.preventDefault();
___ih_hl_end
});
let link = document.getElementById('link');
link.addEventListener('click', function (event) {
logger("Link Event.");
___ih_hl_start
event.preventDefault();
___ih_hl_end
});
</script>
チェックボックスのクリックイベント(43〜47行目)、リンクのクリックイベント(49〜53行目)はpreventDefault
メソッドを呼び出します。
また、イベントの伝搬を確認するため親要素(main
とdiv
)にもイベントハンドラーを登録しました。
プレビューのチェックボックスをクリックしてもチェックマークは付かず、リンクをクリックしてもページが変わることはありません。
また、各イベントハンドラーはテキストを表示しますが、その順番からイベントは伝搬していることが分かります。
※ リセットボタンをクリックするとテキストをリセットします。
なお、preventDefault
メソッドで規定動作を中止するにはEventオブジェクトのcancelable
プロパティがtrue
である必要があります。
イベント伝搬の中止(stopPropagation)
イベント伝搬の中止にはstopPropagationメソッドを使用します。
基本構文
Eventオブジェクト.stopPropagation()
サンプル
<style>
#log {
border: 1px solid black;
padding: 5px;
}
</style>
<main id="main">
<div id="div">
<input id="button" type="button" value="確認">
</div>
</main>
<pre id="log"></pre>
<button id="btn">リセット</button>
<script type="text/javascript">
function logger( text ) {
let log = document.getElementById('log');
log.textContent += text + "\n";
}
function reset( event ) {
let log = document.getElementById('log');
log.textContent = "";
}
let btn = document.getElementById('btn');
btn.addEventListener('click', reset);
let main = document.getElementById('main');
main.addEventListener('click', function() {
logger("Main Event.");
});
let div = document.getElementById('div');
div.addEventListener('click', function() {
logger("Div Event (1).");
___ih_hl_start
event.stopPropagation();
___ih_hl_end
});
div.addEventListener('click', function () {
logger("Div Event (2).");
});
let button = document.getElementById('button');
button.addEventListener('click', function( event ) {
logger("Button Event.");
});
</script>
main
要素、div
要素、input
要素にクリックイベントハンドラーを登録しています。
div
要素には2つ登録しており、1個目(38〜41)はstopPropagation
メソッドを呼び出します。
プレビューの確認ボタンをクリックすると、各イベントハンドラーが実行され、テキストが表示されますが、main
要素のテキストは表示されません。
このことからdiv
要素のクリックイベントでイベントの伝搬が止まっていることが確認できます。
また、div
要素の2個目のイベントハンドラーは実行されていますが、このメソッドも中止するには次のstopImmediatePropagation
メソッドを使用します。
イベント伝搬の即時中止(stopImmediatePropagation)
イベント伝搬の即時中止にはstopImmediatePropagationメソッドを使用します。
ここで言う『即時中止』とは、同じ要素(オブジェクト)のイベントハンドラーも中止するという意味です。
同じ要素(オブジェクト)に複数のイベントハンドラーを登録した場合、stopPropagationメソッドはそれらを実行し、親へのイベント伝搬を中止します。
対してstopImmediatePropagationメソッドは呼び出すと、他の呼び出されていないイベントハンドラーから中止します。
基本構文
Eventオブジェクト.stopImmediatePropagation()
サンプル
<style>
#log {
border: 1px solid black;
padding: 5px;
}
</style>
<main id="main">
<div id="div">
<input id="button" type="button" value="確認">
</div>
</main>
<pre id="log"></pre>
<button id="btn">リセット</button>
<script type="text/javascript">
function logger( text ) {
let log = document.getElementById('log');
log.textContent += text + "\n";
}
function reset( event ) {
let log = document.getElementById('log');
log.textContent = "";
}
let btn = document.getElementById('btn');
btn.addEventListener('click', reset);
let main = document.getElementById('main');
main.addEventListener('click', function() {
logger("Main Event.");
});
let div = document.getElementById('div');
div.addEventListener('click', function() {
logger("Div Event (1).");
___ih_diff_start
- event.stopPropagation();
+ event.stopImmediatePropagation();
___ih_diff_end
});
div.addEventListener('click', function () {
logger("Div Event (2).");
});
let button = document.getElementById('button');
button.addEventListener('click', function( event ) {
logger("Button Event.");
});
</script>
stopPropagationメソッドのサンプルのstopPropagation
メソッドをstopImmediatePropagation
メソッドに変更しました。
プレビューの確認ボタンをクリックし、表示テキストの内容から、先ほどとは変わり2個目のdiv
要素のイベントハンドラーが実行されていないことが確認できます。
これは1個目でstopImmediatePropagation
メソッドが呼び出されたため、以降のイベントハンドラーが中止されたためです。