Web ブラウザで Web ページコンテンツを JavaScript で操作するには,いくつかのブラウザおよび HTML 文書コンテンツを扱うAPIが必要となる。
ここでは https://www.w3.org/TR/html5/Overview.html を基準に対話的Webアプリケーションを作成するのに必要なものについて説明する。
ブラウザ上の特定要素でユーザが起こす働きかけに反応してある処理を 起こすことができる。
たとえば HTML 文書中の特定のdiv要素をクリックすると ダイアログを表示するものは以下のように書ける。
<div onclick="alert('Hi');">
<p>ああああ</p>
</div>
この例は HTML の全要素共通属性である onclick に JavaScript 文を適用したものである。このように特定の働きかけに対しての動作を 定義して進めることを イベント処理 といい,イベントに呼応して動く部分のことを イベントハンドラ という。
ブラウザ共通で有用なイベントについて列挙する。
イベント名 | |
---|---|
click | クリック |
contextmenu |
右クリック(タブレットでは長タップ) |
dblclick |
ダブルクリック |
mousedown |
マウスボタン押下 |
mouseenter |
マウスが入ったとき |
mouseleave |
マウスが出たきたとき |
mousemove |
マウスが動いたとき |
mouseout |
(子孫要素を含め)マウスが出たとき |
mouseover |
(子孫要素を含め)マウスが入ったとき |
mouseup |
押されていたボタンが離されたとき |
keypress |
キーがタイプされたとき |
keydown |
キーが押下されたとき |
keyup |
押されていたキーが離されたとき |
前述のイベント処理例では HTML の属性値への代入でハンドラ登録したが
JavaScript レベルで済ます方法を示す。あるイベント発生を監視し続け,
発生したときになんらかのハンドラを呼ぶような結びつきを作るのが
addEventListener
関数である。
イベントに対してハンドラを結びつける手順はいくらでも考えられるが, 基本的には以下のとおりである。
HTML文書: | イベント処理を行ないたい要素に印を付けておく (id属性などを利用する) |
JavaScript プログラム: | 要素を探し出し addEventListener する |
addEventListener
関数は,イベント捕捉可能なある要素
e に対して以下のように利用する。
e.addEventListener(監視イベント, リスナ[, useCapture]);
リスナ の部分には処理本体となる「関数」を記述する。 別箇所で定義された関数名や、その場で処理を記述する関数式を用いる。
たとえばクリックされたらHelloとウィンドウ表示するWebコンテンツは、 それぞれHTML,JavaScriptで以下のように書く。
----- HTML -----
<p id="someID">クリックしてね</p>
----- JavaScript(1) -----
function clickIT(ev) { alert("Hello"); } document.getElementById("someID").addEventListener("click", clickIT);
----- JavaScript(2) -----
document.getElementById("someID").addEventListener("click", (ev) => { alert("Hello"); });
通常,特定の要素 e で捕捉されるイベントはその親要素にも伝わる。
body 要素から要素 e までに到達するまでのすべての要素には
同じイベントが伝わるが、その複数の要素に同じイベントに対するイベントリスナが
登録してあったとすると、より子孫側の要素に登録されたリスナから先に呼ばれる。
これを先祖側から、に変えたいときは第3引数 useCapture に
false
でない値を指定する。
参考: イベントフロー
JavaScript プログラムを head 要素内で読み込ませる場合は,その場では HTML 文書の要素は読み込み完了していないことに注意する必要がある。 たとえば以下のように body 要素読み込み完了時に発生する load イベントのイベントリスナで、その他全ての必要なイベントリスナ登録を行なうとよい。
function someClickHandler() { alert("Yeaaaah!"); } window.addEventListener("load", function() { var e = document.getElementById("foo"); e.addEventListener("click", someClickHandler, false); }, false);
document オブジェクトに対して発せられるイベントとして
DOMContentLoaded
イベントがある。これは、全てのHTML文書の DOM
構築が終わったときに発せられるので、文書中の特定の要素に対して
働きかける JavaScript プログラムを書くときに以下のように用いる。
document.addEventListener("DOMContentLoaded", 関数, false)
処理の初期化などを行なう関数 を登録することで、全ての文書要素が揃った直後に処理を進められる。
Webページと連動して動作するJavaScriptプログラムの、 典型的な定義例は以下のようになる。
example.js
function myinit() { function func1(){関数定義1....} function func2(){関数定義2...} 処理... } document.addEventListener("DOMContentLoaded", myinit, false);
このようにすることで、ブラウザのトップレベル名前空間には myinit という名前だけが記録され、他のプログラムと衝突する可能性が軽減できる。 あるいは、以下のようにして、名前を一切外部に見せないようにもできる。
document.addEventListener("DOMContentLoaded", () => { function func1(){関数定義1....} function func2(){関数定義2...} 処理... }, false);
※参考: すぐ上のリスト表示部分をクリックすると "foo" と表示される
仕組みでこれを利用している。この文書のソースをみて、
head要素からロードされている
と、すぐ上の div の id の対応を比較してみよ。
既に使用している alert
関数のように、
ユーザに注意を促す簡素なウィンドウを使用する対話処理がいくつか用意されている。
alert
引数に指定した文字列を表示する警告ダイアログを表示する。
OKボタンを押すと消える。ボタンを押すまでは先に進まないので 乱用すると使い勝手が著しく下がることに注意する。
この段落をクリック
confirm
引数に指定した文字列を表示し、OK か Cancel か選ばせるダイアログを表示する。
ユーザが OK を選ぶと true
が返されるので分岐処理に利用できる。
function confirm_test() { var p_confirm = document.getElementById('confirm'); if (confirm("進みますか")) { p_confirm.innerHTML = "進みます!"; } else { p_confirm.innerHTML = "やめます..."; } }
上記のような関数を実行すると、id="confirm" の属性を持つ要素の本文がOKかキャンセルかによって書き換わる。
この段落をクリック
テキスト入力を促すダイアログを表示する。
prompt(プロンプト, 初期値)
プロンプトに指定した文字列を案内文として示し、 入力窓に 初期値 を入れた状態のダイアログが現れる。 入力された文字列が返される。
function prompt_test() { var p = document.getElementById('prompt'); var ini = '名なし'; var name = prompt("お名前は", ini); if (name == '' || name == ini) { p.innerHTML = "教えてくれないなんて水臭いなあ..."; } else { p.innerHTML = "こんにちは " + name + " さん!"; } }
この段落をクリック
setTimeout
関数を用いると一定時間経過後に自動的にある処理を行なわせることができる。
window.setTimeout(関数, ミリ秒[, 引数1, 引数2, ...]);
返却値としてタイマーIDが返される。この値は予定された処理を
中止したい場合に必要になるので保存しておく。中止する場合は
clearTimeout
関数にタイマーIDを与える。
ここを押すとスタート。再クリックで停止。
// 例: 変数の隠蔽化 var count = 10, tmID, infobox = document.getElementById("timeout"); function countDown() { if (--count == 0) { infobox.innerHTML = "ぼかーん"; } else { infobox.innerHTML = count + "秒前"; tmID = setTimeout(countDown, 1000); } } function startCountDown() { tmID = setTimeout(countDown, 1000); infobox.removeEventListener("click", startCountDown, false); infobox.addEventListener("click", stopCountDown, false); } function stopCountDown() { clearTimeout(tmID); infobox.innerHTML = "停めました。"; infobox.removeEventListener("click", stopCountDown, false); } infobox.addEventListener("click", startCountDown, false);
setInterval
関数は、一定時間ごとに繰り返し実行すべき関数を登録できる。
setTimeout
は一度だけだが、これは
clearInterval
関数で停めるまで何度でも呼び出す。setInterval
したままでは
永遠に止まらないのでIDを保存しておいて必ず clearInterval
する。
var intID = setInterval(()=>{処理}, ミリ秒); ... ... clearInterval(intID);
グローバルに参照できる
navigator
オブジェクトを通してユーザのブラウザに関する情報が得られる。
多くのプロパティがあるが、以下のものは参照することが多い。
プロパティ | 意味 |
---|---|
appCodeName | ブラウザ名(非推奨) |
cookieEnabled | クッキー利用可能か |
platform | 使用OS(非推奨) |
userAgent | ブラウザーのユーザーエージェント名 |
language | ユーザの選択した最優先言語 |
以下の例は、navigator
の持つプロパティーのうちいくつかを
表示するものである。
function nav() { x = ['appCodeName', 'appName', 'appVersion', 'platform', 'product', 'userAgent', 'language']; var i, s = ''; for (var j=0; j < x.length; j++) { i = x[j]; s += (s>'' ? "\n" : '') + i + '=' + navigator[i]; } document.getElementById("navInfo").textContent = s; }
ここをクリックで navigatore オブジェクト一覧表示
nav2()★★★★★★
location
オブジェクトは、参照中のURLに関連する値を管理する。
主なプロパティを示す。
プロパティ | 意味 |
---|---|
href | 現在のURL(変更するとページ移動する) |
protocol | http: あるいは https: |
host | URLのホスト部分(ポート番号指定を含む) |
hostname | URLホスト名 |
port | URLのポート番号 |
pathname | 先頭の "/" を含むURLパス名 |
search | URLのうち "?" と後続するクエリ文字列 |
hash | URLのうち "#" と後続するIDを含んだパス名 |
username | ドメイン名の前に指定されたユーザ名 |
password | ドメイン名の前に指定されたパスワード |
とくに location.href
は有用で、
以下のようにして別のURLに遷移させることができる。
location.href = "https://www.koeki-u.ac.jp/"; //ここをクリック!
この場合はブラウザの履歴を書き換えるため、「戻る」ボタンで
以前いたページに戻ることができる。履歴を書き換えず、
現在のページをすり替えることができるのが
location.replace()
で表示中のページを履歴に残さずに
別のページに移動させることができる。
location.reload()
はページをリロードする。
window, document オブジェクトもリファレンス参照しておくとよい。