JavaScriptでイベントを登録する方法です。jQuery時代は登録している意識があまりなかったかもしれませんが、JavaScriptの場合は意識的に登録しないとイベントとして動かすことができません。
イベント登録の基本と、よくあるイベントのパターン、そして初心者(自分)がつまづく部分などを紹介していけたらと思っています。
要素に対して「これはイベントだよ!」とJavaScriptで登録する必要があります
JavaScriptでイベントを登録する方法
イベントを登録するには、addEventListener()
を使います。
(参考)→ EventTarget.addEventListener() – Web API | MDN
イベント対象となる要素に対して、「イベントの種類」「イベント時の内容」を登録するようなイメージですね。具体的なコードで見ていきましょう!
ボタンのクリック時にログを出力
例として、ボタンのクリック時にログを出力するシンプルなイベントを作ってみます。まずはボタンをHTMLで作ります。
<button class="button" type="button">ボタン</button>
次に作成したボタンに対してイベントを登録していきます。
const button = document.querySelector(".button");
button.addEventListener("click", function() {
console.log( "クリックされました" );
});
対象の要素に対して、addEventListener
関数で以下の2つを登録するのが基本となります。
- 第一引数・・・イベント種類
- 第二引数・・・コールバック関数(イベント発火時の処理を記載する場所)
コールバック関数は外だしも可能
上記の例では、第二引数のコールバック関数を直接記載していますが(無名関数と言います)、これを通常の関数のように外に書いて呼び出すことも可能です。
外に出した場合は、関数名を第二引数に記載します。注意点としては、ここで引数を与えないことですね…。引数を与えるとイベントの登録時点で関数が実行されてしまいます。
(わたしも最初ハマりました…)
button.addEventListener("click", handleClick);
function handleClick() {
console.log( "クリックされました" );
}
対象の要素を取得する方法
クリック時にどの要素がクリックされたか取得したケースは多いかと思います。方法としては2パターンあって、this
を使う方法と、event.target
を使う方法です。
コールバック関数はevent
を受け取れるようになっているので、event.target
を使う場合は忘れずに引数に指定してあげてください。
const button = document.querySelector(".button");
button.addEventListener("click", function(event) {
console.log( "クリックされました" );
console.log( event.target );
console.log( this );
});
実行してみると、両方とも同じ要素を取得できていることが分かります。
複数の要素にイベントを登録
例えば、すべての.button
クラスに対して同一のイベントをつけたいケースもあるかもしれません。JavaScriptで複数イベントを登録する場合は、各要素に対して1つ1つ登録していく必要があります。
以下のようにクラス名が同じで3つのボタンにイベントを付与するケースを見ていきます。
<button class="button" type="button">ボタン</button>
<button class="button" type="button">ボタン2</button>
<button class="button" type="button">ボタン3</button>
ダメなパターン
すべてのクラスなのでquerySelectorAll
で要素を取得し、jQueryの感覚でaddEventListener
に登録しようとしてみると、、、
const buttons = document.querySelectorAll(".button");
buttons.addEventListener("click", function(event) {
console.log( "クリックされました" );
});
「Uncaught TypeError: buttons.addEventListener is not a function
」とエラーとなってしまいます。querySelectorAll
で取得できた値に対して、イベント登録する関数は使えません!と怒られている感じですね。
大丈夫なパターン
これをループさせて1つ1つにイベントを登録してみます。
const buttons = document.querySelectorAll(".button");
buttons.forEach(function(button) {
button.addEventListener("click", function(event) {
console.log( event.target.textContent + "がクリックされました" );
});
});
これで期待どおりに、それぞれのボタンにイベントを登録することができました。
JavaScriptで登録できる主要イベント
JavaScriptで登録できる主要なイベントを見ていきます。
クリック
const button = document.querySelector(".button");
button.addEventListener("click", function(event) {
console.log( "イベントの種類:" + event.type );
});
スクロール
window
に対して、scroll
イベントを付与します。位置の取得は、3パターンあるようで全部メモしておきました。
window.addEventListener("scroll", function(event) {
console.log( "イベントの種類:" + event.type );
console.log( "スクロール位置:" + window.pageYOffset );
console.log( "スクロール位置:" + window.scrollY );
console.log( "スクロール位置:" + document.documentElement.scrollTop );
});
ページの読み込み
ページの読み込みはDOMContentLoaded
とload
の2種類があります。以下のような違いとなります。
DOMContentLoaded
・・・HTML構文の解析が終わったらload
・・・画像やスクリプトなどすべての読み込みが終わったら
load
の方が発火するまでに時間がかかります。ローディング処理で画面を隠す際はload
で隠しておくのが一般的かと思います。
DOMContentLoaded
document.addEventListener("DOMContentLoaded", function() {
console.log( "DOMContentLoadedの読み込み完了!" );
});
load
window.addEventListener("load", function() {
console.log( "loadの読み込み完了!" );
});
フォーカス
最近、地味によく使うfocus
も他のイベントと同様に登録できます。
const button = document.querySelector(".button");
button.addEventListener("focus", function(event) {
console.log( "イベントの種類:" + event.type );
});
フォーカスが外れる場合のイベントは、blur
となります。
const button = document.querySelector(".button");
button.addEventListener("blur", function(event) {
console.log( "イベントの種類:" + event.type );
});
マウスホバー
マウスホバーをJavaScriptで表現するには、マウスカーソルが要素に乗っている時、マウスカーソルが要素から外れた時の2つを登録する必要があります。
const button = document.querySelector(".button");
// マウスカーソルが要素に乗っている時
button.addEventListener("mouseover", function(event) {
console.log( "イベントの種類:" + event.type );
});
// マウスカーソルが要素から外れた時
button.addEventListener("mouseout", function(event) {
console.log( "イベントの種類:" + event.type );
});
おわり
JavaScriptでイベント(クリックやスクロール等)を登録する方法と主要イベントをまとめました。
注意点をおさらいすると、以下の2点だけ意識すれば少なくとも使うことはできるようになるかと思います。
- インベント登録時のコールバック関数を定義する際は関数名だけを指定すること
- 複数の要素に同じクラス名が付与されていても、それぞれの要素にイベントを登録すること