- ・イベントの登録
- ・イベントハンドラーの取り消し
- ・一度だけイベントハンドラーを実行
- ・イベントのキャンセル
- ・イベントの伝播をキャンセル
- ・画面遷移時のイベント
- ・ページ読み込みのイベント
- ・ページ読み込み中のイベント
- ・スクロール時のイベント
- ・その他スクロール関連
イベントの登録
EventTarget . addEventListener()
イベントは、addEventListenerメソッドで登録します。
- target.addEventListener(type, listener [, options]);
- target.addEventListener(type, listener [, useCapture]);
- target.addEventListener(type, listener [, useCapture, wantsUntrusted ]);
targetは対象要素。
引数
- type:イベント名(文字列)イベント名一覧はこちらを参照
- listener:イベントハンドラー(コールバック関数)
- options以下省略可能な引数は以下を参照
(キャプチャリングやバブリング等いろいろな設定ができるので目を通しておいて下さい。)
addEventListener
ckickイベントによる例
<div id="btn">クリック</div>
// 要素の取得
let btn = document.querySelector('#btn');
// イベントの登録
btn.addEventListener('click', function(event){
console.log('クリックされました'); // クリックされました
})
コールバック関数の引数eventには検知したイベントに関するさまざまな情報が格納されています。
この引数eventはEvent型のEventオブジェクトなります。
Eventオブジェクトに格納されている情報はイベントのタイプごとに異なります。
たとえばclickイベントにはclientXおよびclientYというプロパティがありクリックされた座標がわかります。
targetというプロパティはclickイベントを起こした要素(ここでは#btn)がわかります。
イベントハンドラーの取り消し
EventTarget . removeEventListener()
addEventListenerで登録されたイベントハンドラーは、removeEventListenerで取り消すことができます。
- target.removeEventListener(type, listener[, options]);
- target.removeEventListener(type, listener[, useCapture]);
引数に関しては以下を参照。
removeEventListener
<div id="btn">クリック</div>
※ 無名関数では機能しないので、名前付きの関数を指定します。
// 要素の取得
let btn = document.querySelector("#btn");
function sam() {
console.log("クリックされました");
}
// イベントの登録
btn.addEventListener("click", sam);
setTimeout(() => {
// 3秒後にイベントハンドラーを削除
btn.removeEventListener("click", sam);
}, 3000);
一度だけイベントハンドラーを実行
イベントハンドラーを一度だけ実行してから削除するには、addEventListenerの第三引数のonceオプションにtrueを指定します。一度実行されたイベントハンドラーは自動的に削除されます。
※この方法はIE11ではサポートされていません。
<div id="btn">クリック</div>
// 要素の取得
let btn = document.querySelector("#btn");
function sam() {
console.log("クリックされました");
}
// イベントの登録
// 一度だけ"クリックされました"が表示される
btn.addEventListener("click", sam, {once: true});
(IEで動作させる場合)
// 要素の取得
let btn = document.querySelector("#btn");
function sam() {
// 関数がイベントハンドラーとしてしてされた場合
// thisはイベントの登録対象(btn)を示す
this.removeEventListener('click', sam);
console.log("クリックされました");
}
// イベントの登録
// 一度だけ"クリックされました"が表示される
btn.addEventListener("click", sam);
イベントのキャンセル
Event . preventDefault()
イベントオブジェクトのpreventDefaultメソッドを実行すると、デフォルトのイベントの挙動がキャンセルされます。
aタグの場合だとhref属性に指定されている場所へ画面遷移するのがデフォルトのイベント挙動ですが、preventDefaultメソッドを実行する事で画面遷移をキャンセルします。
<a href="">クリック</a>
// 要素の取得
let a = document.querySelector("a");
function sam(event) {
// デフォルトのイベント挙動をキャンセル
event.preventDefault();
console.log("クリックされました");
}
// イベントの登録
// a要素をクリックする度に"クリックされました"を表示
a.addEventListener("click", sam);
イベントの伝播をキャンセル
Event . stopPropagation()
イベントは、子要素から親要素へ伝播する性質を持っています。その伝搬をキャンセルするにはstopPropagationメソッドを使います。
<section id="sec01">
<p>クリック</p>
</section>
伝搬をキャンセルしていない場合
伝搬をキャンセルしていない場合はpをクリックしても親の#sec01の伝搬しているので、pを1回クリックで「クリックされました クリックされました」と2回表示される
// 要素の取得
let sec01 = document.querySelector("#sec01");
let p = document.querySelector("p");
function sam(event) {
console.log("クリックされました");
}
// イベントの登録
sec01.addEventListener("click", sam);
// pタグをクリックしたら伝搬して親のイベントも実行される
p.addEventListener("click", sam); // クリックされました クリックされました
伝搬をキャンセルした場合
伝搬をキャンセルした場合は親の#sec01には伝搬しないので、pをクリックした場合pに登録したイベントのみが実行されるので「クリックされました」と1回表示される
// 要素の取得
let sec01 = document.querySelector("#sec01");
let p = document.querySelector("p");
function sam(event) {
event.stopPropagation(); // 伝搬をキャンセル
console.log("クリックされました");
}
// イベントの登録
sec01.addEventListener("click", sam);
// 伝搬はキャンセルされているので親のイベントは実行されない
p.addEventListener("click", sam); // クリックされました
画面遷移時のイベント
画面遷移する直前の処理はaddEventListenerのbeforeunloadイベントを使います。
window.addEventListener('beforeunload', function(event) {
event.preventDefault();
event.returnValue = ''; // Chrome対策
});
ページ読み込みのイベント
Window: load
loadイベントは、ページ全体が、スタイルシートや画像などのすべての依存するリソースを含めて読み込まれたときに発生します。
window.addEventListener('load', (event) => {
//ページが完全に読み込まれた後に実行する処理
});
上記と動作はおなじですが、以下の方がポピュラーな書き方かもしれません。
window.onload = (event) => {
//ページが完全に読み込まれた後に実行する処理
};
その他にDOMContentLoadedイベントがありますが、こちらはHTMLが読み込まれた段階で実行されるため、スタイルシートや画像の読み込みが完了するのを待たずに発生します。
ページ読み込み中のイベント
Document . readyState
ページの読み込み中に何らかの処理をしたい場合はreadyStateプロパティを使います。
if (document.readyState === "loading") {
// ページが読み込み中の処理
} else {
// ページ読み込み完了後の処理
}
正確にはreadyStateプロパティは、ページの読み込みの状況を表します。
読み込みの状況で「loading」の箇所の値が変化します。詳しくはリンク先をご覧ください。
スクロール時のイベント
window(ページ)のスクロール
window . onscroll
windowがスクロールされた際に実行されます。
window.onscroll = () => {
// windowがスクロールされた際に呼び出される処理
let y = window.scrollY;
console.log(y); // y軸のスクロール量を表示
};
x軸のスクロール量を取得の場合はwindow.scrollYをwindow.scrollXにします。
またpageYOffsetプロパティは、scrollYプロパティへのエイリアスになりますので挙動は同じです。
window . addEventListener(‘scroll’, ….)
addEventListenerで「scroll」を指定して、スクロール時のイベント実行です。
window.addEventListener("scroll", function () {
// windowがスクロールされた際に呼び出される処理
let y = window.pageYOffset;
console.log(y); // y軸のスクロール量を表示
});
要素のスクロール
指定した要素内のスクロールイベントは、addEventListenerで、ページスクロールの「window.scrollY」を「this.scrollTop」に変更します。
<ul id="list">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
</ul>
#list{
height: 100px;
overflow-y: scroll;
}
// 要素取得
const list = document.querySelector('#list')
list.addEventListener("scroll", function (event) {
let y = this.scrollTop;
console.log(y); // 要素のy軸のスクロール量を表示
});
onscrollプロパティの場合
// 要素取得
const list = document.querySelector('#list')
list.onscroll = function() {
let y = this.scrollTop;
console.log(y)
};
スクロールイベントの制御
スクロール終了時に処理を実行
●setTimeout関数を使う方法
スクロールを終了したタイミングで処理を実行したい時は、scrollイベントのコールバック関数内でsetTimeout関数を使用します。
<section id="sec01" style="height: 3000px;"></section>
var timeoutId;
window.addEventListener("scroll", function () {
// スクロールを停止して500ms後に終了
clearTimeout(timeoutId);
timeoutId = setTimeout(function () {
// スクロールを停止後の処理
console.log('スクロール停止'); // スクロール停止後に表示
}, 500);
});
●npmのthrottle-debounceを使う
throttle-debounceは、連続処理の間引き(throttle)や連続処理後の遅延実行(debounce)を提供するモジュールです。
throttle、debounceは、自作で書いてある記事をちょくちょく見かけるのですが、どれもコードが長くもう少し手軽に使えるものがないかという事で、lodashなどがありましたがパフォーマンスがよくないという意見もあるようなのでnpmのthrottle-debounceが良いのかなという結論になりました。
※インストール方法等は省力します。
その他スクロール関連
- ・スクロール量が状況によって変化した場合の対応
【参考】JSでのスクロール連動エフェクトにはIntersection Observerが便利 - ・要素の大きさの取得
【参考】https://cookbook.xrea.jp/js-cookbook/display/scroll.php#heading3 - ・スクロール位置を取得
【参考】https://cookbook.xrea.jp/js-cookbook/display/scroll.php#heading8 - ・スクロールを制御(アニメーション移動)
【参考】https://cookbook.xrea.jp/js-cookbook/display/scroll.php#heading12 - ・画面の移動(アニメーション移動)
【参考】https://cookbook.xrea.jp/js-cookbook/display/scroll.php#heading17