イベントとは
今回も、引き続きこちらの本を参考にさせていただいた。
岩田宇史「いちばんやさしいJavaScriptの教本」(インプレス)
まずイベントを理解するにあたり、JavaScriptで実装できる動作の一例を紹介する。
- ボタンをクリックしたら、入力フォームが表示される
- マウスポインタが当たったら、文字の色が変わる
- 入力フォームに文字を入力したら、その文字数が表示される
どれも、ユーザー側の動作と動作の結果実行されることが対になっている。上記の例では、以下の動作がユーザー側の動作に該当するだろう。
- ボタンをクリックする
- マウスポインタを特定の箇所に当てる
- 入力フォームに文字を入力する
これらのユーザー側の動作がイベントと呼ばれているものだ。
イベントの設定
上記で紹介した動作を実現するためには、イベントとイベントに伴い実行される内容を設定しなければならない。その方法には幾つか種類があるのだが、今回はイベントリスナーによる設定を行ってみる。
早速プログラムを書いてみた。
ボタンをクリックしたら、入力フォームが表示される
このためにプログラムに必要となる要素は、当然ボタンと入力フォームだ。id="button"とid="form"の要素を取得する。
使用するイベントはclickだ。このイベントは、その名の通り要素をクリックした時に発生する。
HTML
HTMLでは通常の入力フォームを記述する。
<head>
<!-- 省略 -->
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<button id="button">フォーム表示</button><br>
<form action="" id="form">
<textarea id="textarea" name="textarea"></textarea></br>
<input type="submit" id="submit" value="送信">
</form>
<script src="js/app.js"></script>
</body>
CSS
CSSで入力フォームの表示を阻止している。ボタンがクリックされたらフォームを表示させるため、あえてnoneにする。
# form {
display: none;
}
JavaScript
ここでイベントリスナーが登場する。イベントリスナーはイベントとイベントに伴い実行される内容をそれぞれ引数に取り、処理を実行する。
イベントに伴い実行される内容は、基本的に無名関数として記述する。名前付き関数で引数をとる場合は、無名関数の中で呼び出さなければならない。
var button = document.getElementById('button');
var form = document.getElementById('form');
button.addEventListener('click', function() {
form.style.display = 'block';
});
動作の流れはこうだ。
-
documentオブジェクトのgetElementByIdメソッドで、HTMLに記述されているid="button"とid="form"の要素をオブジェクトとして取得する。 -
buttonオブジェクトのaddEventListenerメソッドを使用する。 - 上記メソッドの
第1引数はイベントであるclick、第2引数はイベントに伴い実行される内容を無名関数として記述する。 - この場合、
formオブジェクトのstyleプロパティから呼び出されるdisplay(CSSで設定されるプロパティ)にblockを代入している。 - 結果、CSSで設定されていた
display: none;がdisplay: block;に置き換わり、フォームが表示される。
マウスポインタが当たったら、文字の色が変わる
ここで必要な要素は、文字(を囲んでいる要素)だ。id="greeting"の要素を取得する。
今回使用するイベントはmouseoverだ。これは、マウスポインタが該当する要素の上に乗った時に発生するイベントだ。
HTML
<body>
<div id="greeting">
<h1>ようこそ!</h1>
</div>
<script src="js/app.js"></script>
</body>
JavaScript
今回はイベントの発生により、CSSのcolorプロパティを変更している。マウスポインタが要素の上に乗った時、文字の色が赤に変わる。
var greeting = document.getElementById('greeting');
greeting.addEventListener('mouseover', function() {
greeting.style.color = '#FF0000';
});
入力フォームに文字を入力したら、その文字数が表示される
入力フォームに文字を入力した場合、新しい要素が挿入され、そこに文字数が表示される。入力フォームそのものであるid="textarea"の要素と新要素divの取得が必要となる。
また、使用するイベントkeyupはキーを離した時(=入力文字数)に発生する。
HTML
<body>
<button id="button">フォーム表示</button><br>
<form action="" id="form">
<textarea id="textarea" name="textarea"></textarea></br>
<input type="submit" id="submit" value="送信">
</form>
<script src="js/app.js"></script>
</body>
JavaScript
var button = document.getElementById('button');
var form = document.getElementById('form');
button.addEventListener('click', function() {
form.style.display = 'block';
});
// 以下を追記
var textarea = document.getElementById('textarea');
var text_counter = document.createElement('div');
var parent = textarea.parentElement;
parent.insertBefore(text_counter, null);
textarea.addEventListener('keyup', function(event) {
console.log(event.key);
// console.log(textarea.value);
text_counter.innerHTML = "<h2>現在" + textarea.value.length + "文字入力しています</h2>";
});
動作を解説する。
-
documentのgetElementByIdメソッドによりtextareaオブジェクトを取得する。 -
documentのcreateElementメソッドでdivタグを作成しtext_counterへ代入。オブジェクトとして扱う。 -
textareaオブジェクトのparentElementメソッドで親要素を取得し、さらに親要素のinsertBeforeメソッドでtext_counterオブジェクトを追加する。 -
textareaオブジェクトのaddEventListenerメソッドで、動作のタイミングとなる第1引数keyupを指定する。 - 第2引数である無名関数で、
text_counterオブジェクトのinnerHTMLメソッドにより入力文字数を示す文を挿入する。
入力文字数自体は、textarea.value.lengthで簡単に取得できる。また、console.log(textarea.value);を試してみると、1文字入力する度にvalue属性の内容(=入力内容)がコンソールに出力される。
さらに、今回の無名関数では第1引数としてeventを指定している。これはイベントオブジェクトと呼ばれており、イベントに関する情報が格納されている。
この情報を使用したい場合は、無名関数の第1引数として指定すれば、関数内で使用することができる。今回はconsole.log(event.key)の記述で、eventオブジェクトのkeyプロパティの内容がコンソールに出力される。
オブジェクトのメソッドを使用する
今までイベントに伴う動作には既存のメソッドを使用してきた。今回は独自のメソッドを定義し、それを使用してみる。
オブジェクトの定義
メソッドを定義するには、まず元となるオブジェクトが必要だ。以下の構文で、オブジェクトを変数thanksに代入している。
定義している内容は、messageプロパティとthanksMessメソッドの2つだけだ。
thanksMessメソッドのreturn文にあるthisは、この構文内ではthanksオブジェクト自身を表している。this.messageでthanksオブジェクトのmessageプロパティつまり"<h2>ありがとう!</h2>"を呼び出している。
var thanks = {
message: "<h2>ありがとう!</h2>",
thanksMess: function() {
return this.message;
}
}
ボタンをクリックしたら、メッセージを表示する
id="thanks_button"のボタンがクリックされたら、id="message"の中にメソッドの結果(メッセージ)が表示される仕組みだ。
HTML
<body>
<input type="button" id="thanks_button" value="メッセージ表示">
<div id="message"></div>
<script src="js/app.js"></script>
</body>
JavaScript
他のイベントリスナーの記述法とほぼ変わらない。ただし、メソッドを呼び出す場合はthanks.thanksMess()のように、オブジェクト名.メソッド名と記述しなくてはならない。
var thanks = {
message: "<h2>ありがとう!</h2>",
thanksMess: function() {
return this.message;
}
}
// 以下を追記
var thanks_button = document.getElementById('thanks_button');
var message = document.getElementById('message');
thanks_button.addEventListener('click', function() {
message.innerHTML = thanks.thanksMess();
});
イベントハンドラについて
イベントを記述するもう1つの方法がイベントハンドラだ。よくHTMLのbuttonタグ内でonClickという記述を見かけるが、これがそうだ。また、JavaScript内にも記述が可能だ。
しかし、その結果実行できる関数は1つに限られるため、参考にした基本書の中ではあまり推奨されていなかった。
イベントハンドラについては、こちらの記事が参考になる。
JavaScriptのイベントハンドラ一覧-PHP & JavaScript Room
まとめ
結局記事の作成には2日間かかってしまったが、JavaScriptの概要はざっくり把握できたと思う。次はVue.jsにチャレンジしてみたいのがだが、jQueryにも興味がある。
自分が作成しているアプリは学習も兼ねた超小規模なものなので、それに合わせて選択したいと思う。様々なライブラリ・フレームワークの動作確認も兼ねて。
さらに、今回の学習ではイベント時の動作は実行できたが、その逆ができなかった。(もう一度クリックするとフォームが非表示になる等・・・)色々試してみたが、CSSの要素の取得が難しい。解決策としてイベントハンドラによる記述例も見かけたが、時と場合により使い分けるものなのだろうか?
課題も多いが、今回はここまで。