10章 イベント
イベントドリブンプログラミング
- p266 ブラウザにイベントが発生した時の関数を登録しておいて、呼び出してもらう
- IE8以前は独自の実装になっている
イベントハンドラ/イベントリスナの設定
- イベントハンドラは、1つの要素・イベントに1つしか設定できない
- イベントリスナは、複数設定できる
- p267 HTML要素の属性に指定する(イベントハンドラ)
- DOM要素のプロパティに指定する(イベントハンドラ)
- EventTarget.addEventListener()を利用する(イベントリスナ)
HTML要素の属性に指定する
DOM要素のプロパティに指定する
- HTMLファイルとJavaScriptファイルを分けている場合、HTMLファイルの中のJavaScriptコードは少なくしたほうが保守性が上がる
- 要素.onclick=関数 として、DOM要素のイベントハンドラプロパティに関数を設定する
- p269 この方法で設定すると、HTMLのonclickで指定したイベントハンドラは無効になる
EventTarget.addEventListener()を利用する
- DOM Level2で定義されている
- IE8以前では使用できない(attachEvent()を利用)
- 第3引数で、キャプチャリングフェーズか、パブリングフェーズかを指定。DOM Level3では省略すると後者になる
- HTMLのイベントハンドラやDOMのプロパティに設定した場合、パブリングフェーズで実行
- IE8以前ではパブリングフェーズのみ
- p270 イベントリスナの実行順
- DOMLevel2では順不同だった
- DOMLevel3で、登録順と定義
- イベントターゲット、イベントタイプ、フェーズの組み合わせが同じものには、同じ関数をイベントリスナとして複数設定できない。あとから登録した方が無視される
- イベントリスナオブジェクト
- 通常は、関数を渡すが、ブラウザの実装で、handleEvent()メソッドを持ったオブジェクトを渡しても動作するようになっている
- p271 イベントターゲット…イベントを発火させた要素。イベントオブジェクトのtargetプロパティで参照できる
- リスナーターゲット…イベントリスナが設定されている要素。イベントオブジェクトのcurrentTargetプロパティで参照できる
イベント発火
- mousemoveは、マウスが動くたびに発動するので、設定すると負荷が大きい。利用は注意
イベントの伝播
- HTMLは入れ子構造で出来上がっている
- イベントは、入れ子構造に対して、キャプチャリングフェーズ、ターゲットフェーズ、パブリングフェーズという3つのフェーズに分かれて処理される
キャプチャリングフェーズ
- windowオブジェクトからDOMツリーを辿ってイベントが発生したオブジェクトまで順番に降りておく
- このタイミングで実行するイベントがキャプチャリングフェーズ
ターゲットフェーズ
- p273 イベントターゲットに登録されているイベントリスナやイベントハンドラを処理
パブリングフェーズ
- イベントターゲットからDOMツリーを上に辿っていくフェーズ
- このツリー上のノードに登録されたイベントリスナがこのタイミングで実行される
- clickイベントはどの要素が必要とするか不明なので全てのDOMツリーをたどる
- focusイベントはその要素にだけ必要なイベントなのでパブリングしない
キャンセル
標準イベント
DOM Level2で定義されているイベント
- HTMLEvent…読み込みやフォーカスの移動、ウィンドウサイズの変更など
- MouseEvent…マウス関連のイベント
- UIEvent…パブリング可能なフォーカスの移動や要素の活性化
- MutationEvent…文章やノード、属性の変更
DOM Level3で定義されているイベント
- p277 MutationEventとMutationNameEventは非推奨
- p278 各種一覧
- p279 イベントの発火順
独自イベント
- p280 createEvent()メソッドでイベントオブジェクトを生成
- そのイベントオブジェクトを対象となるノードのdispatchEvent()メソッドで発動する
- IEでは、createEventObject()、fireEvent()メソッドを使う
- initEvent(イベントタイプを指定する文字列
- dispatchEvent()を呼び出すと、その場でイベント処理の実行が始まり、戻り値を返す
- キューに積んで処理するなどしたい場合は、setTimeout()を利用してdispatchする
- 通常の関数ではなく、イベント登録しておくのは、処理の追加が容易になる。独自のコールバックではなく、仕様であるaddEventListener()で呼び出した方がすっきりし、他のモジュールとの連携も楽になる
散歩リンクで、通信関連で使えそう