Webブラウザに関連する主要オブジェクト

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 押されていたキーが離されたとき

JavaScript からのリスナ登録

前述のイベント処理例では 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引数 useCapturefalseでない値を指定する。

参考: イベントフロー

JavaScript プログラムを head 要素内で読み込ませる場合は,その場では HTML 文書の要素は読み込み完了していないことに注意する必要がある。 たとえば以下のように body 要素読み込み完了時に発生する load イベントのイベントリスナで、その他全ての必要なイベントリスナ登録を行なうとよい。

function someClickHandler() {
  alert("Yeaaaah!");
}
window.addEventListener("load", function() {
  var e = document.getElementById("foo");
  e.addEventListener("click", someClickHandler, false);
}, false);

DOMContentLoaded イベント

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 関数のように、 ユーザに注意を促す簡素なウィンドウを使用する対話処理がいくつか用意されている。

Timer

setTimeout

setTimeout 関数を用いると一定時間経過後に自動的にある処理を行なわせることができる。

window.setTimeout(関数, ミリ秒[, 引数1, 引数2, ...]);

返却値としてタイマーIDが返される。この値は予定された処理を 中止したい場合に必要になるので保存しておく。中止する場合は clearTimeout 関数にタイマーIDを与える。

ここを押すとスタート。再クリックで停止。

countdown.js

// 例: 変数の隠蔽化
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

setInterval 関数は、一定時間ごとに繰り返し実行すべき関数を登録できる。 setTimeout は一度だけだが、これは clearInterval 関数で停めるまで何度でも呼び出す。setInterval したままでは 永遠に止まらないのでIDを保存しておいて必ず clearInterval する。

var intID = setInterval(()=>{処理}, ミリ秒);
  ...
  ...
clearInterval(intID);

Navigator

グローバルに参照できる 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;
}

nav2()★★★★★★

location

location オブジェクトは、参照中のURLに関連する値を管理する。 主なプロパティを示す。

プロパティ意味
href現在のURL(変更するとページ移動する)
protocolhttp: あるいは https:
hostURLのホスト部分(ポート番号指定を含む)
hostnameURLホスト名
portURLのポート番号
pathname先頭の "/" を含むURLパス名
searchURLのうち "?" と後続するクエリ文字列
hashURLのうち "#" と後続するIDを含んだパス名
usernameドメイン名の前に指定されたユーザ名
passwordドメイン名の前に指定されたパスワード

とくに location.href は有用で、 以下のようにして別のURLに遷移させることができる。

location.href = "https://www.koeki-u.ac.jp/"; //ここをクリック!

この場合はブラウザの履歴を書き換えるため、「戻る」ボタンで 以前いたページに戻ることができる。履歴を書き換えず、 現在のページをすり替えることができるのが location.replace() で表示中のページを履歴に残さずに 別のページに移動させることができる。

location.reload() はページをリロードする。

その他

window, document オブジェクトもリファレンス参照しておくとよい。