JavaScript イベント処理 (2)
JavaScript イベント処理 (1)こちらは昔の記事です。整理中・・・。
addEventListener サンプル
addEventListener でイベントをつける。
- TestJS_keyevent_div02.html
div でキー入力を受ける。
JavaScript キー入力処理 - TestJS_dnd_text_file01.html
ドラッグ&ドロップでテキストファイルを開く。
JavaScript ファイル処理 FileAPI
アロー関数でイベント処理
アロー関数は IE では使用できませんでしたが 2020年代は多用します。
1) 昔 : function() で記述。 element.onclick = function(event){ 処理 } 2) 現在: アロー関数で記述。 element.onclick = event => 処理;
function(){ ... }
を使ったコールバックの書き方は IE 時代までの古い話なので
2020年代は使わない方が良いです。下で説明する this
を気にする話が出てきます。
JavaScript: 考古学
this の指すオブジェクトに注意
1) アロー関数内の this と 2) 従来の function(){ ... }内の this で、 this の指すオブジェクトが変わる場合があります。 「this を束縛しない」、「this を束縛する」 といった説明で出てきます。
イベントを出す側の処理
イベントを登録して使う側の話ではなくて、 イベントを出す側についての話です。 自分で作成したクラスでイベントを登録したり、 イベントを出したりする処理を用意します。
GUI の部品を使うときにイベント処理の話が出てきます。 JavaScript のプログラムでイベントリスナー(コールバックの関数) を登録して利用するという話がよく出てきますが、 こちらはすでにある部品をユーザーとして使うだけの話で、 中で具体的にどのような処理をしているのかは ブラックボックスになっています。
● ユーザーがリスナー関数を登録して利用する例 window.addEventLisnter("load", function(){....}); 1) addEventLisnter() の中で具体的にどのような処理をしているのか?、 2) どのようにしてリスナー関数が呼ばれるのか? 1),2) は、ユーザー側は普段は気にしないブラックボックスの話です。
GUI 部品を作るときには、 リスナーを登録したりリスナー関数を実行したりする処理を用意する話が出てきます。 上のブラックボックスの部分を自分で作って用意します。
MDN に簡易実装例があります。Event1.js - こちらは上 MDN のソースを流用したもの。 ソースの内容は、 1)イベントの種類ごとにリスナーのリストを用意する。 this.listeners = {}; に格納する。 {} の中身は イベント名1:[], //リスナーを格納する配列, イベント名2:[], //リスナーを格納する配列, ... イベント名は、"click", "change" などのイベントの種類。 リスナーを格納する配列には、イベント処理の関数を入れる。 2)イベントリスナーを登録する処理、削除する処理、実行する処理を用意する。 リスナーを登録 addEventListener() リスナーを削除 removeEventListener() イベント処理を実行 dispatchEvent() ・自分のクラスで、イベント出す条件が整ったときに dispatchEvent() を呼び出し、this.listeners["イベント名"] に登録された関数を 登録順に実行します。
上の処理の仕方は他のプログラミング言語でも出てきます。 Java や C# でも同じような仕組みの処理を行い、 似た名前の関数(メソッド) が出てきます。
上の話は慣れてないと複雑に見える話です。 個々の部品が他の部品に依存しないようにし、 部品の独立性・汎用性を高くするためこのような仕組みを使います。
HTMLElement も祖先のクラスは EventTarget です
HTML 要素 ( p タグ、div タグなど) のクラスは、 はじめからイベント処理を付けて処理する前提の部品として作られています。 祖先のクラス (インターフェイス) は EventTarget になっています。
◎ HTML 要素のクラスの親子関係 EventTarget イベント処理のインターフェイス + Node 汎用のノードのクラス (要素やテキストノードなど) + Element 要素のクラス (HTML, XML などの要素) + HTMLElement HTML 要素のクラス (HTML の要素に限定) + HTMLSpanElement span タグのクラス + HTMLParagraphElement p タグのクラス ...
まとめ
汎用性のある GUI 部品を作ろうとすると、以下の知識も必要になります。
- イベント処理の仕組み
イベントを使うユーザー側の話ではなく、イベント処理を提供する側の話。 - オブジェクト指向とクラスの継承
基本的な部品に機能を追加するときに必要になります。 - インターフェイス (API)の設計
関数名やプロパティ名などユーザーから見えてる部分と、 普段は見なくてよい部分をはっきりと分ける。 これがないと、ユーザーはどこを見れば良いのか使い方の分からない部品になります。
JavaScriptでは、 外に公開している部分と隠蔽しているブラックボックスの部分をきれいに分ける仕組みがないので困る・・・ 大規模なアプリケーションに適さないと言われる理由の1つ。 Java や C# では interface などを使って分離します。