読者です 読者をやめる 読者になる 読者になる

O'REILLYの"JavaScript"を読む 第17章 イベントとイベント処理

持ち回りの読書会も気がついたら17章まできていた。ということで今回はイベント。
ブラウザ上で、ユーザが何か行動したときに(クリックとかハイパーリンク上にマウスカーソル置くとか)、ブラウザはイベントを生成する。ある要素で発生したイベントを処理したい時、イベントハンドラをその要素に登録する。

イベント処理は複雑

イベント処理モデルには、互換性のない3つのモデルが使われている。

オリジナルイベントモデル

HTML4標準である程度規定されている。また非公式(?)だがDOMレベル0 APIの一部とみなされている。機能は限定的だがすべてのJavaScript対応ブラウザで定義されている

標準イベントモデル

DOMレベル2で標準化されたモデル。InternetExplorer以外の最近のブラウザでサポートされている

InternetExplorerイベントモデル

IEのイベントモデル。標準イベントモデルの高度な機能も一部サポートされている

基本的なイベント処理

基本的なイベント処理は、イベントハンドラJavaScriptコードの文字列として記述し、onclickみたいな属性の値として使用する。

イベントとイベントタイプ

オリジナルイベントモデルでは、イベントはWebブラウザ内で抽象化されていて、JavaScriptから直接イベントを操作することは不可能である。このモデルでは、イベントに応じて呼び出されるイベントハンドラの名前で区別する。
そしてこのモデルでは、イベント処理を行うコードをHTML要素で指定する。

<input type="button" value="hoge" onClick="alert('testtest');"</input>
デバイス依存イベントとデバイス独立イベント
  • デバイスに依存するイベント: onClick(マウス)、onkeypress(キーボード)
  • デバイス独立イベント: onsubmit、onchange等

プロパティとしてのイベントハンドラ

ドキュメント中のHTML要素はドキュメントツリー中に対応するDOM要素を持ち、JavaScriptオブジェクトのプロパティがHTML要素の属性に対応する。
そのため、HTML要素がイベントハンドラ属性を持てば、その要素オブジェクトのプロパティを使って属性に登録されたイベントハンドラを参照することができる。また、イベントハンドラプロパティに対して関数を設定すれば、ドキュメントの要素にイベントハンドラを設定できる。

document.f1.b1.onClick=function() {alert('hoge');}
document.f1.b1.onClick=someFunction;

なお、イベントハンドラを定義する場合は関数呼び出しの結果ではなく、関数自身をプロパティに設定する。

イベントハンドラの戻り値

イベントに対してブラウザが何らかのデフォルトの処理を行う場合、falseを使うことで処理を中止できる。

<form action="search.php"
     onsubmit="if(this.elements[0].value.length == 0) return false;">
</form>

上のコードの場合、フォームに記入漏れがあれば送信できないようになる。

イベントハンドラとthisキーワード

イベントハンドラを定義すると、ドキュメント要素に関数を保存することになる。このイベントハンドラが呼び出される場合、イベントが発生した要素のメソッドとして呼び出されるため、thisキーワードが参照するのはイベントが発生した要素。

イベントハンドラのスコープ

HTML属性の値としてJavaScriptコード文字列を設定してイベントハンドラを定義した場合、暗黙にJavaScript関数を定義することになる。この方法で定義されたイベントハンドラ関数のスコープは通常のグローバル関数を定義する場合のスコープと異なる。スコープチェーンの先頭がCallオブジェクトであることは同じだが、スコープチェーンの次のオブジェクトはグローバルオブジェクトではなく、イベントハンドラを起動したオブジェクトとなる。

<form>
  <input id ='b1' type='button' value="button1"  onclick="alert(this.form.b2.value);">
  <input id ='b2' type='button' value="button2"  onclick="alert(form.b2.value);">
  <input id ='b3' type='button' value="button3"  onclick="alert(b2.value);">
  <input id ='b1' type='button' value="button1"  onclick="alert(this.form.b2.value);">
</form>