イベント
値としての関数
JavaScript では、関数も値の一種です。 したがって、他の値と同じように、変数に代入したり、関数の引数や戻り値として使用したりすることができます。
function greet() {
document.write("Hello World");
}
const func = greet;
func();
上の例では、const func = greet; の行で変数 func に関数 greet を代入しています。関数を値として扱うときは、関数呼び出し式の括弧は使用しません。これにより、関数が代入された変数を経由してその関数を実行できます。
イベントハンドラ
オブジェクトのプロパティとして関数を利用することもできます。
document.getElementById が返すオブジェクトの onclick プロパティには、要素がクリックされたときに実行される関数を指定できます。
ボタンのクリック、フォームへの入力、ページの読み込みなど、Web ページ上で発生するあらゆるアクションを総称してイベントと呼びます。
このようなイベントの処理を行うのがイベントハンドラで、onclick 関数はその一例です。
<button id="greet-button" type="button">クリック</button>
function clicked() {
document.write("Hello World");
}
const greetButton = document.getElementById("greet-button");
greetButton.onclick = clicked;
この例では、HTML 要素の id 属性に greet-button が指定されている HTML 要素を表すオブジェクトの onclick プロパティに対し、関数 clicked を代入しています。これにより、ボタンがクリックされたとき、clicked 関数が実行されるようになります。
下のコードは意図したとおりに動作しません。何が間違っているのでしょうか。
function clicked() {
document.write("Hello World");
}
const greetButton = document.getElementById("greet-button");
greetButton.onclick = clicked();
答えは、最後の行が clicked から clicked() に変わってしまっていることです。関数は、カッコをつけた式が評価されるタイミングで実行されます。このため、
greetButton.onclick = clicked();
では代入より前、式 clicked() が評価されたタイミングで clicked 関数が実行されてしまいます。
上の例では、画面上にはじめから表示されていたボタンが、ボタンをクリックしたときに削除されています。これは、document.write をすべての要素の表示が終わった後に実行すると、画面上のすべての要素を一度削除するという挙動をとるためです。このため、現代の JavaScript において、document.write 関数が使用されることはほとんどありません。
演習
押すと大きく赤文字が表示される「びっくり箱」のようなボタンを作ってみましょう。
document.write 関数を使うと、画面上にあったボタンが消えてしまいます。また、文字色や文字サイズを変えることも困難です。
document.write 関数の代わりに、先ほどの DOM の章で扱った方法を使って HTML 要素を JavaScript で操作するとよいでしょう。
Hello World! を表示する場所document.write 関数を使わずに「Hello World! を表示する」という挙動を実現するためには、あらかじめ中身のない HTML 要素を置いておき、その要素の textContent プロパティを操作するとよいでしょう。
<div id="greeting"></div>
解答例: びっくり箱
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<title>Title</title>
</head>
<body>
<div id="greeting"></div>
<button id="button">ボタン</button>
<script src="./script.js"></script>
</body>
</html>
const greetingElement = document.getElementById("greeting");
const buttonElement = document.getElementById("button");
function onGreetingButtonClick() {
greetingElement.textContent = "Hello world!!";
greetingElement.style.color = "red";
greetingElement.style.fontSize = "40px";
}
buttonElement.onclick = onGreetingButtonClick;