今回はイベントについて学んでいきましょう。JavaScriptによるアプリケーションを作成するうえでは,イベントは欠かすことができない要素です。

 ここでは,旧来より使われてきたイベントハンドラのおさらいと,イベントハンドラの問題点を考察します。そして,イベントハンドラに置き換わるW3C DOMイベントモデルの基礎を学んでいきます。

イベントとは

 イベントとは,ブラウザ上で発生した出来事全般のことを表します。例えば,ブラウザに表示された画面上でマウスをクリックしたり,テキストボックスに文字を入力するといったように,閲覧者が何か操作したときにイベントが発生します。また,HTMLがブラウザに読み込まれたり,別のページに移動したという現象もイベントとして認識されます。

 まずはじめに,旧来より使われてきたイベントハンドラについておさらいしましょう。

イベントハンドラ

 イベントをJavaScriptで扱うためには,イベントハンドラを使ってきました。イベントハンドラはJavaScriptのコーディングの際に,非常に直観的でわかりやすいため,様々なシーンで使われています。

 本連載でも何度かサンプルで使ってきましたが,ここで改めて使い方を見ていきましょう。

 まずは,HTML要素内にイベントハンドラをセットする場合を見てみましょう。


<div id="box" onclick="javascript:alert('Clicked !')">xxx</div>

 この使い方は良くご存じのことでしょう。HTML要素内に,onclick属性を使ってJavaScriptコードを直接セットしています。このdiv要素をマウスでクリックすれば,"Clicked !"と表示されたアラートウィンドウがポップアップします。

 しかし,これではHTML要素内にJavaScriptコードが混在することになり,HTMLの見た目が煩雑になります。そのため,HTMLからJavaScriptを完全に切り離す方法として,次のようなコーディングスタイルが使われてきました。


window.onload = function() {
  var box = document.getElementById('box');
  box.onclick = function() {
    alert("Clicked !");
  }
};

 windowオブジェクトにonloadイベントハンドラをセットすることで,HTMLがブラウザにロードされてから実行したい処理を指定することができます。このonloadイベントハンドラにセットする関数の中では,div要素の要素ノードオブジェクトを取り出し,それに対してonclickイベントハンドラをセットしています。

 このコードは,最初のサンプルと同じ結果が得られます。

イベントハンドラの問題点

 実は,この連載でイベントハンドラの使い方を解説したいわけではありません。イベントハンドラは簡単に利用できるという反面,問題点もあります。その問題点とは,同じ要素に同じイベントハンドラを複数定義できないという点です。  この問題点を具体的に見てみましょう。

◎HTML


<script type="text/javascript" src="cs1.js"></script>
<script type="text/javascript" src="cs2.js"></script>

◎cs1.js


window.onload = function() { alert('cs1'); }

◎cs2.js


window.onload = function() { alert('cs2'); }

 このサンプルは,二つの別々の処理をcs1.jsとcs2.jsに分け,script要素でそれぞれをロードしています。cs1.jsとcs2.jsは,ただ単にアラートウィンドウを表示させるだけです。

 この状況を見て,アラートウィンドウは2回表示されるものだと思われた方がいらっしゃるのではないでしょうか。実は,アラートウィンドウは1回しか表示されません。しかも表示されるのは,"cs2"です。

 イベントハンドラは,同じ要素に同じイベントハンドラを複数定義しようとすると,後から定義したもので上書きされてしまうのです。このサンプルでは,cs1.jsとcs2.jsいずれもwindowオブジェクトに対してonloadイベントハンドラをセットしています。通常は,script要素のsrc属性にセットされたjsファイルは上から順番にロードされますので,cs1.jsが処理された後に,cs2.jsが処理されます。すると,cs1.jsでwindowオブジェクトにonloadイベントハンドラをセットしたにもかかわらず,cs2.jsでそれが上書きされてしまうのです。

 AJAXが注目される以前では,JavaScriptの用途が限られていたため,この問題点が注目されることが少なかったといえます。また,一人でJavaScriptをコーディングしていれば,これを回避することも可能だったといえるでしょう。

 近年は,JavaScriptの用途が広範囲にわたり,複雑な処理が求められるようになりました。一つのHTMLに,数多くのjsファイルをロードすることもあるでしょう。また,様々なアクションをページに組み込む場合には,アクションの内容に応じて,別々の人が分担して作ることもあるでしょう。

 このような状況下では,ここで見てきたイベントハンドラの問題点が必ず表面化してきます。