HTML Living Standard  第3部 Javascript 10 イベント


 

10 イベント

10.1  イベントハンドラ

イベントは、マウスボタンをクリックした、ページが読み込まれたなどの動作が起こったときに発生します。イベントハンドラは、このイベントを検出し、イベントに処理を与えるのに使用します。イベントハンドラによって、発生したイベントごとに処理を実行することができます。

イベントハンドラを設定する方法には次の3つがあります。

(1) インラインイベントハンドラ

イベントハンドラは、記述例のように onXXXXX="イベントが発生したときに実行する命令" という形式で、HTML の タグの中にインラインイベントハンドラ属性として書くことができます。

イベントが発生したときに実行する命令は、セミコロン(;)で区切ることにより複数の文を記述することも可能です。また、関数を呼び出すこともできます。関数は通常、<head><script>~</script></head> の間で定義します。

記述例
  <span onclick="click イベントが発生したときに実行する命令">クリックして</span>

インラインイベントハンドラ属性には主に次のものがあり、インラインイベントハンドラ属性が記述された要素で発生した各種イベントを補足することができます。

イベントハンドライベント発生理由
onabort読み込みが中断された
onblur入力フォーカスを失った
oncancelダイアログを中断して閉じる
oncanplayメディアの再生が可能になった
oncanplaythroughメディアの全編を再生できる状況になった
onchange入力内容が変更された
onclickマウスの左ボタンがクリックされた
oncloseウィンドウが閉じられた
oncontextmenuマウスの右ボタンがクリックされた
ondblclickマウスの左ボタンがダブルクリックされた
ondragドラッグされている
ondragendドラッグが終了された
ondragenterドラッグしながら要素に入った
ondragleaveドラッグしながら要素から出た
ondragoverドラッグ中に要素に重なった
ondragstartドラッグが開始された
ondrop要素にドロップされた
ondurationchangeメディアの再生時間が変更された
onemptiedコンテンツが空になった
onendedメディアの再生が終了した
onerrorメディアのロード中にエラーが発生した
onfocus入力フォーカスを得た
oninput入力を取得したとき
oninvalid送信時に無効な値がある
onkeydownキーが押された
onkeypressキーを押して離した
onkeyupキーを離した
onloadページの読み込みが完了した
onloadeddataメディアデータがロードされた
イベントハンドライベント発生理由
onloadedmetadataメタデータがロードされた
onloadstart実際にロードが始った
onmousedownマウスボタンが押された
onmouseenterマウスポインタが要素に入った
onmouseleaveマウスポインタが要素から出た
onmousemoveマウスポインタが移動した
onmouseoutマウスポインタが要素の外へ移動した
onmouseoverマウスポインタが要素の上に移動した
onmouseupマウスボタンが放された
onmousewheelマウスホイールが回転した
onpauseメディアの再生が一時休止になった
onplayメディア再生の準備ができた
onplayingメディア再生が開始された
onprogressメディアデータが取得されている
onratechange再生速度が変更された
onresetフォームがリセットされた
onresizeウィンドウの大きさが変えられた
onscroll要素の内容がスクロールされた
onseekedシークが終了した
onseekingシークが行われている
onselect要素内の文字列が選択された
onshowウィンドウが表示された
onstalledメディアデータをフェッチできなかった
onsubmit送信ボタンが押された
onsuspendメディアデータのフェッチが停止した
ontimeupdate再生位置が変更された
ontoggledetails 要素の開閉が切り替わった
onvolumechangeボリュームが変更された
onwaitingバッファリングでメディアは一時停止した

次の例では、onclick のとき(クリックされたとき)に実行されるよう設定しています。

イベント情報は、ほとんどのブラウザでは自動的に event という変数に設定されます。イベント情報については、「10.4 イベントオブジェクト」 を参照してください。

なお、 draw(this) の this は、それを記述した span 要素を示します。this については、「7.5 this」 を参考にしてください。

<head>
  <script>
  function draw(my) {
    my.style.color = event.offsetX < my.offsetWidth / 2 ? "red" : "black";
    // ここで使用する this は window を示す
  }
  </script>
</head>
<body>
  <span onclick="draw(this);">クリックして</span>   // draw(this) の this は span 要素を示す
</body>

「クリックして」の前半部分をクリックすると、文字が赤くなります。後半部分だと黒くなります。

実行例

イベント情報は、ほとんどのブラウザでは自動的に event という変数に設定されますが、古い などは設定されないことがありますので、そのときは以下のように取り出す必要があります。

    var event = arguments.callee.caller.arguments[0];   // event イベント情報

(2) Javascript

Javascript で、ウィンドウ、ドキュメント、エレメントなどの onXXXXX を設定することもできます。この例でも、span 要素の onclick のときに設定しています。また、登録した処理を削除するには、onclick に null を代入します。

なお、onXXXXX への代入を複数回行っても、イベントが発生したときには最後に代入した処理のみが実行されます。つまり、代入によって処理は上書きされてしまうわけです。したがって、複数の処理を登録し実行されるようにはできません。

イベント情報は、ほとんどのブラウザでは自動的に event という変数に設定されます。イベント情報については、「10.4 イベントオブジェクト」 を参照してください。

なお、onclick で呼び出される関数内で使用されている this は、onclick が記述された span 要素を示しています。this については、「7.5 this」 を参考にしてください。

記述例
<body>
  <span id="s">クリックして</span>
  <script>
  document.getElementById("s").onclick = function() {   // event イベント情報
    this.style.color = event.offsetX < this.offsetWidth / 2 ? "red" : "black";
    // ここで使用する this はイベントの発生元である span 要素を示す
  }
  </script>
</body>

「クリックして」の前半部分をクリックすると、文字が赤くなります。後半部分だと黒くなります。

実行例

また、head 要素内に定義した関数を登録するような場合には、次のように記述します。

なお、draw 関数内で使用されている this は、draw 関数を呼び出す onclick が記述された span 要素を示しています。this については、「7.5 this」 を参考にしてください。

記述例
<head>
  <script>
  function draw(color) {
    return function() {
      this.style.color = event.offsetX < this.offsetWidth / 2 ? color : "black";
      // ここで使用する this はイベントの発生元である span 要素を示す
    };
  }
  </script>
</head>
<body>
  <span id="s">クリックして</span>
  <script>
  document.getElementById("s").onclick = draw("red");   // draw(this) としたら、this は window を示す
  </script>
</body>

「クリックして」の前半部分をクリックすると、文字が赤くなります。後半部分だと黒くなります。

実行例

イベント情報は、ほとんどのブラウザでは自動的に event という変数に設定されますが、古い などは設定されないことがありますので、そのときは以下のように引数として受け取る必要があります。

  document.getElementById("s").onclick = function(event) { }   // event イベント情報
  function draw(color) {
    return function(event) { }   // event イベント情報
  }

(3) DOM 方式

DOM Level 3 Events ではイベント登録用メソッドとして addEventListener が定義されています。addEventListener の第一引数にイベントの種類(onXXXXX の XXXXX の部分)を文字列として指定します。

第二引数には、イベントが発生したときに呼び出されるメソッド名もしくは直接メソッドを記述します。呼び出されたメソッドには、発生したイベントの情報が引数として渡されます。

なお、第三引数は省略可能で省略した場合は false になります。第三引数については、この下の「イベントの伝播」を参照してください。

また、登録したメソッドを削除するのは removeEventListener です。addEventListener のときとまったく同じ引数でないと削除することはできません。ただし、addEventListener で直接メソッドを記述した場合は、removeEventListener でまったく同じに記述しても別物と判断されますので、削除することはできません。

なお、addEventListener でメソッドを複数回登録したら、イベントが発生したときには登録したすべてが実行されます。つまり、onXXXXX への代入と違い、複数の処理を登録することができるわけです。

オブジェクト.addEventListener(event, func, useCapture)

event 発生ときに func を実行するようにイベントリスナーを設定する。

引数 event:イベントの種類

引数 func:関数

引数 useCapture:Capture(捕捉)フェーズを使用する(true)、使用しない(false) 規定値

戻り値:なし


オブジェクト.removeEventListener(event, func, useCapture)

指定した引数とまったく同じであるイベントリスナーを削除する。ただし、addEventListener のとき、第二引数に直接メソッドを記述していた場合は削除できない。

引数 event:イベントの種類

引数 func:関数

引数 useCapture:Capture(捕捉)フェーズを使用する(true)、使用しない(false) 規定値

戻り値:なし

イベント情報は、ほとんどのブラウザでは自動的に event という変数に設定されます。イベント情報については、「10.4 イベントオブジェクト」 を参照してください。

また、addEventListener で指定する関数に引数がない場合、関数名の後ろに () を付けてはいけてはいけません(この例では draw() としてはいけません)。

記述例
<head>
  <script>
  function draw() {
    this.style.color = event.offsetX < this.offsetWidth / 2 ? "red" : "black";
    // ここで使用する this はイベントの発生元である span 要素を示す
  }
  </script>
</head>
<body>
  <span id="s">クリックして</span>
  <script>
  document.getElementById("s").addEventListener("click", draw, false);
  </script>
</body>

「クリックして」の前半部分をクリックすると、文字が赤くなります。後半部分だと黒くなります。

実行例

イベント情報は、ほとんどのブラウザでは自動的に event という変数に設定されますが、古い などは設定されませんので、以下のように引数として受け取る必要があります。

記述例
function draw(event) { }

引数を持つ関数を登録するような場合には、次のように記述します。

なお、draw 内で使用している this はイベントの発生元である span 要素を示しています。this については、「7.5 this」 を参考にしてください。

記述例
<head>
  <script>
  function draw(color) {
    return function() {
      this.style.color = event.offsetX < this.offsetWidth / 2 ? color : "black";
      // ここで使用する this はイベントの発生元である span 要素を示す
    };
  }
  </script>
</head>
<body>
  <span id="s">クリックして</span>
  <script>
  document.getElementById("s").addEventListener("click", draw("red"), false);
  </script>
</body>

「クリックして」の前半部分をクリックすると、文字が赤くなります。後半部分だと黒くなります。

実行例

イベント情報は、ほとんどのブラウザでは自動的に event という変数に設定されますが、古い などは設定されないことがありますので、そのときは以下のように受け取る必要があります。

    return function(event) { }   // event イベント情報

また、addEventListener() の第二引数にオブジェクトを渡すと、イベント発生時にはそのオブジェクトの handleEvent() メソッドが呼び出されます。

記述例
  <span id="s">クリックして</span>
  <script>
  var obj = {
    handleEvent:
      function() {   // s は id="s" の span 要素
        s.style.color = event.offsetX < s.offsetWidth / 2 ? "red" : "black";
      }
  };

  document.getElementById("s").addEventListener("click", obj, false);
  </script>

「クリックして」の前半部分をクリックすると、文字が赤くなります。後半部分だと黒くなります。

実行例

イベント情報は、ほとんどのブラウザでは自動的に event という変数に設定されますが、古い などは設定されないことがありますので、そのときは以下のように取り出す必要があります。

      function(event) { }   // event イベント情報

10.2  イベントの伝播

同じイベントハンドラーを複数の要素に指定した上で input 要素に対して何かをした場合、イベントは以下のような順番でDOMの中を伝播していきます。

  1. Captureフェーズ
  2. Targetフェーズ
  3. Bubblingフェーズ(?)
記述例
<div>
  <form id="f">
    <input id="t" type="text" size="5">
  </form>
</div>

上記からわかるとおり、イベントが発生したときオブジェクトによってはイベントが到達するタイミングが2回存在し、またその順番が変わることが分かります。

addEventListener() の第3引数である useCapture の設定によって、以下のようにイベントをどのフェーズで割り当てるかを指定することができます。

ただし、Targetフェーズだけなのか Bubblingフェーズもあるのかはイベントによるようです。例えば、click イベントは Bubblingフェーズもありますが、focus イベントは Targetフェーズだけです。また、mouseenter イベントはどうやっても外側にある親要素からイベントが発生する(子要素と同時には発生しない)ので、イベントの伝播は起こらないようです。

記述例
<label>useCapture
<input type="radio" name="capture" value="true" checked onclick="userCapture(true);">true  
<input type="radio" name="capture" value="false" onclick="userCapture(false);">false
</label><br>
<br>
<span id="d11"></span> <span id="d12"></span> <span id="d13"></span>

<div id="d">div
  <form id="f">form
    <input id="t" type="text" size="5" placeholder="input">
  </form>
</div>
  
<script>
var use = true;
function userCapture(status) {
  use = status;
  addEvent();
}
function addEvent() {
  t.removeEventListener('click', exec1, !use);
  f.removeEventListener('click', exec2, !use);
  d.removeEventListener('click', exec3, !use);
  t.addEventListener('click', exec1, use);
  f.addEventListener('click', exec2, use);
  d.addEventListener('click', exec3, use);
}
var n = 1;
function clear() {
  n = 1;
  document.getElementById("d11").textContent="";
  document.getElementById("d12").textContent="";
  document.getElementById("d13").textContent="";
  t.style.backgroundColor = "white";
  f.style.backgroundColor = "white";
  d.style.backgroundColor = "white";
}
function exec1(event) {
  exec(event, "input");
}
function exec2(event) {
  exec(event, "form");
}
function exec3(event) {
  exec(event, "div");
}
function exec(event, element) {
  event.target.style.backgroundColor = "pink";
  if (n > 3) return;
  document.getElementById("d1" + n++).textContent=element;
}

var t = document.getElementById("t");    // input 要素
var f = document.getElementById("f");    // form 要素
var d = document.getElementById("d");    // div 要素
t.addEventListener('mouseleave', clear, false);
addEvent();
</script>

useCapture を設定して、下の入力欄をクリックしてください。入力欄の上にイベントを処理した要素名が表示されます。

実行例

10.3  イベントの種類

主なイベントには次のようなものがあります。

イベントの種類説明
マウス・イベントマウスまたは類似のユーザーアクションによって起動されるイベント
キーボード・イベントキーボードまたは類似のユーザーアクションによって起動されるイベント
ウィンドウ・イベントwindow オブジェクト、あるいは body 要素において有効なイベント
フォーム・イベントフォーム内のアクションにより起動されるイベント
ドラッグ・イベントドラッグによって起動されるイベント
クリップボード・イベントコピー & ペーストなどによって起動されるイベント
印刷・イベント印刷、プレビューなどによって起動されるイベント
メディア・イベント動画、画像やオーディオのようなメディアにより起動されるイベント
アニメーション・イベントスタイルシートのアニメーションなどによって起動されるイベント
サーバー送信・イベントサーバーへの送信などによって起動されるイベント
タッチ・イベントタッチなどによって起動されるイベント
その他・イベントその他のイベント

10.3.1  マウス・イベント

マウスまたは類似のユーザーアクションによって起動されるイベントです。

イベント説明イベントが発生する主な要素イベントオブジェクト
clickマウスクリックで発生するイベントbody 要素内の要素MouseEvent
contextmenu右クリックで発生するイベントbody 要素内の要素
dblclickマウスのダブルクリックで発生するイベントbody 要素内の要素
mousedownマウスボタンを押したときに発生するイベントbody 要素内の要素
mouseenterマウスポインタが進入したときに発生するイベントbody 要素内の要素
mouseleaveマウスポインタが進出したときに発生するイベントbody 要素内の要素
mousemoveマウスポインタを移動したときに発生するイベントbody 要素内の要素
mouseoverマウスポインタを要素の上に移動したときに発生するイベントbody 要素内の要素
mouseoutマウスポインタを要素の外へ移動したときに発生するイベントbody 要素内の要素
mouseupマウスボタンを放したときに発生するイベントbody 要素内の要素
mousewheelマウスホイールを回転したときに発生するイベントbody 要素内の要素

(1) マウスボタン(click、dblclick、mousedown、mouseup、contextmenu)

マウスのボタンをクリックしたときに発生するイベントです。

記述例
<div id="d"></div>
<div id="b">click!</div>    <!-- ボタン -->
<script>
var prevTime = 0;
function dispEvent(event) {
  event.preventDefault();    // デフォルトの処理を行わない
  var time = event.timeStamp;
  if (time - prevTime >= 500) {  // 0.5秒以上たったら消す
    prevTime = time;
    document.getElementById("d").textContent = "";
  }
  document.getElementById("d").textContent += event.type + " ";
}
var b = document.getElementById("b");
b.addEventListener('click', dispEvent, false);
b.addEventListener('dblclick', dispEvent, false);
b.addEventListener('mousedown', dispEvent, false);
b.addEventListener('mouseup', dispEvent, false);
b.addEventListener('contextmenu', dispEvent, false);
</script>

1回だけのクリックの場合、mousedown → mouseup → click の順に、

ダブルクリックの場合、mousedown → mouseup → click → mousedown → mouseup → click → dblclick の順に、

右クリックの場合、mousedown → mouseup → contextmenu の順に発生します。

実行例

(2) マウス移動(mouseenter、mouseleave、mousemove、mouseover、mouseout)

マウスポインターが移動したときに発生するイベントです。

記述例
<div id="d"></div>
<div id="p"></div>    <!-- 黄色い四角 -->
<script>
var mousemoveCount = 0;
function clear() {
  mousemoveCount = 0;
  document.getElementById("d").textContent = "";
}
function dispEvent(event) {
  event.preventDefault();    // デフォルトの処理を行わない
  if (event.type == "mousemove") {
    if (++mousemoveCount > 1) {
      var s = document.getElementById("d").textContent;
      var n = s.lastIndexOf("(");
      document.getElementById("d").textContent = s.substring(0, n) + "(" + mousemoveCount + ") ";
    }
    else {
      document.getElementById("d").textContent += event.type + "(1) ";
    }
  }
  else {
    mousemoveCount = 0;
    document.getElementById("d").textContent += event.type + " ";
  }
}
document.body.addEventListener('mouseleave', clear, false);
var p = document.getElementById("p");
p.addEventListener('mouseenter', dispEvent, false);
p.addEventListener('mouseleave', dispEvent, false);
p.addEventListener('mousemove', dispEvent, false);
p.addEventListener('mouseover', dispEvent, false);
p.addEventListener('mouseout', dispEvent, false);
</script>

黄色い四角にマウスポインターを入れて、そのあとそこから抜けてください。

mouseover → mouseenter → mousemove → ... → mousemove → mouseout → mouseleave の順に発生します(ただし、mousemove は移動するたびに発生しますので発生回数を表示するようにしています)。

実行例

mouseover と mouseenter はともにマウスポインターが要素の上に載った(要素内に入った)場合に発生します。

mouseout と mouseleave はともにマウスポインターが要素の上からいなくなった(要素外に出た)場合に発生します。

これらの違いは、mouseover と mouseout は、イベントが発生した要素だけでなくその外側の要素にもイベントが発生するのに対して、mouseenter と mouseleave は、イベントが発生した要素の外側にはイベントが発生しないことにあります。

記述例
スタイルシート
<style>
  span.outer {
    color:orange;
  }
  span.inner {
    color:green;
  }
</style>
  
ボディ
<div id="d"></div>
<div id="p">    <!-- 外側のオレンジ色の四角 -->
外側
<div id="c">内側</div>    <!-- 内側の緑色の四角 -->
</div>
<script>
function dispEvent(event, style) {
  event.preventDefault();    // デフォルトの処理を行わない
  document.getElementById("d").innerHTML += "<span class= '" + style + "'>" + event.type + "</span> ";
}
document.body.addEventListener('mouseleave', function() {document.getElementById("d").innerHTML = "";}, false);
var p = document.getElementById("p");
p.addEventListener('mouseenter', function(event) {dispEvent(event, "outer");}, false);
p.addEventListener('mouseleave', function(event) {dispEvent(event, "outer");}, false);
p.addEventListener('mouseover', function(event) {dispEvent(event, "outer");}, false);
p.addEventListener('mouseout', function(event) {dispEvent(event, "outer");}, false);
var c = document.getElementById("c");
c.addEventListener('mouseenter', function(event) {dispEvent(event, "inner");}, false);
c.addEventListener('mouseleave', function(event) {dispEvent(event, "inner");}, false);
c.addEventListener('mouseover', function(event) {dispEvent(event, "inner");}, false);
c.addEventListener('mouseout', function(event) {dispEvent(event, "inner");}, false);
</script>

したがって、外側から内側にマウスポインターを移動させたときは、mouseoutmouseovermouseovermouseenter の順に発生します。つまり、外側から内側に移動したときに一度外側から出るので外側に mouseout、そして内側に入るので内側に mouseover と mouseenter が発生します。ただし、mouseover は外側にもイベントが発生するので上記のようになるわけです。

また、内側から外側にマウスポインターを移動させたときは、mouseoutmouseoutmouseleavemouseover の順に発生します。この場合は、内側から出るので内側に mouseout と mouseleave が発生します。この内 mouseout は外側にもイベントが発生します。そして、外側の上にマウスポインターが移動するので、外側に mouseover が発生するわけです。

実行例

(3) マウスホイール(mousewheel)

マウスホイールが動かされたときに発生するイベントです。

記述例
<div id="d"></div>
<div id="p"></div>    <!-- 黄色い四角 -->
<script>
var mousemoveCount = 0;
function clear() {
  mousewheelCount = 0;
  document.getElementById("d").textContent = "";
}
function dispEvent(event) {
  event.preventDefault();    // デフォルトの処理を行わない
  if (++mousemoveCount > 1) {
    var s = document.getElementById("d").textContent;
    var n = s.lastIndexOf("(");
    document.getElementById("d").textContent = s.substring(0, n) + "(" + mousewheelCount + ") ";
  }
  else {
    document.getElementById("d").textContent += event.type + "(1) ";
  }
}
var p = document.getElementById("p");
p.addEventListener('mousewheel', dispEvent, false);
p.addEventListener('mouseleave', clear, false);    // 表示を消す
</script>

黄色い四角内で、マウスホイールを回転させると mousewheel イベントが発生し、mousewheel とイベントの発生回数が表示されます。なお、この例ではマウスポインターを黄色い四角から出すとイベント名を消すようにしています。

実行例

10.3.2  キーボード・イベント

キーボードまたは類似のユーザーアクションによって起動されるイベントです。

イベント説明イベントが発生する主な要素イベントオブジェクト
keydownキーが押されたときに発生するイベントinput、textareaKeyboardEvent
keypressキーを押して放したときに発生するイベントinput、textarea
keyupキーを放したときに発生するイベントinput、textarea

記述例
<span id="d1"></span> <span id="d2"></span> <span id="d3"></span><br>
<input id="t" type="text">

<script>
var n = 1;
function clear() {
  n = 1;
  document.getElementById("d1").textContent="";
  document.getElementById("d2").textContent="";
  document.getElementById("d3").textContent="";
}
function dispEvent(event) {
  if (event.type == "keydown")
    clear();
  document.getElementById("d" + n++).textContent=event.type;
}
var t = document.getElementById("t");
t.addEventListener('blur', clear, false);
t.addEventListener('keydown', dispEvent, false);
t.addEventListener('keypress', dispEvent, false);
t.addEventListener('keyup', dispEvent, false);
</script>

下の入力欄で何かキーを押してください。押したときに keydown が発生し、文字キーの場合はそれに続いて keypress が発生します。そして、キーを離すと keyup が発生します。

古い は、[Backspace]や[Insert]などの文字ではないキーでも keypress が発生します。他のブラウザでは発生しません。

実行例

10.3.3  ウィンドウ・イベント

window オブジェクト、あるいは body 要素において有効なイベントです。

イベント説明イベントが発生する主な要素イベントオブジェクト
beforeunload文書がアンロードされようとしているときに発生するイベントwindowBeforeUnloadEvent
errorエラーが発生したときに発生するイベントwindow、input、textareaUIEvent
hashchange文書が変わったときに発生するイベントwindowHashChangeEvent
load文書をロードするときに発生するイベントwindow、body、imgUIEvent
pagehideウィンドウが非表示にされるときに発生するイベントwindowPageTransitionEvent
pageshowウィンドウが表示されたときに発生するイベント windowPageTransitionEvent
resizeウィンドウをリサイズしたときに発生するイベントwindowUIEvent
scroll要素のスクロールバーをスクロールしたときに発生するイベントwindow、body 要素内の要素UIEvent
unloadユーザが文書を離れたときに発生するイベントwindow、bodyUIEvent

(1) ページ切り替え(load、beforeunload、unload)

load イベントはページ読み込み後に発生します。

beforeunload イベントは現在のページから他のページへ移る前に発生します。

unload イベントは現在のページから他のページへ移ろうとした際に beforeunload イベントの後に発生します。

記述例(iframeを持つ親ドキュメント)
<div id="d"></div>
記述例(iframe内の子ドキュメント)
<div class="switch" onclick="go();">go</div>
<script>
function go() {
  window.addEventListener('beforeunload', function() {parent.document.getElementById("d").textContent+="beforeunload ";}, false);
  window.addEventListener('unload', function() {parent.document.getElementById("d").textContent+="unload ";}, false);
  location.href='another.htm'
}
window.addEventListener('load', function() {parent.document.getElementById("d").textContent="load ";}, false);
</script>

load イベント発生ときに load と表示します。このページが読み込まれたときには load イベントがすでに発生していますので、load という文字も表示されています。

[ go ] ボタンをクリックすると別ページに移動します。別のページに移るときに beforeunload イベントが発生します。beforeunload イベント発生ときに beforeunload と表示します。

beforeunload イベントに続いて unload イベントが発生します。unload イベント発生ときに unload と表示します。

load beforeunload unload と表示されることを確認してください。

実行例

(2) 表示(pageshow、pagehide)

pageshow イベントはページが表示された際に load イベントに次いで発生します。

pagehide イベントは他のページに移動するなどして、現在のページが隠された際に beforeunload イベントの後で、unload イベントに先だって発生します。

記述例(iframeを持つ親ドキュメント)
  <div id="d"></div>
記述例(iframe内の子ドキュメント)
<div class="switch" onclick="go();">go</div>
<script>
function go() {
  window.addEventListener('pagehide', function() {parent.document.getElementById("d").textContent="pagehide ";}, false);
  location.href='another.htm'
}
window.addEventListener('pageshow', function() {parent.document.getElementById("d").textContent="pageshow ";}, false);
</script>

pageshow イベント発生ときに pageshow と表示します。このページが読み込まれたときには pageshow イベントがすでに発生していますので、pageshow という文字も表示されています。

[ go ] ボタンをクリックすると別ページに移動します。別のページに移るときに pagehide イベントが発生します。pagehide イベント発生ときに pagehide と表示します。

pageshow pagehide と表示されることを確認してください。

実行例

(3) ページサイズ変更(resize)

resize イベントはブラウザのウィンドウの大きさが変えられるたびに発生します。

記述例
<div id="d1"></div>
<div id="d2"></div>

<script>
function dispEvent(event) {
  document.getElementById("d1").textContent = event.type;
}
function size() {
  document.getElementById("d2").textContent="(" + w.innerWidth + "," + w.innerHeight + ")";
}
var w = this.parent;    // window オブジェクト
w.addEventListener('load', size, false);
w.addEventListener('resize', function(event) {dispEvent(event); size()}, false);
</script>

ブラウザの大きさを変えてみてください。

実行例

(4) ハッシュ(hashchange)

ハッシュとは、URL の # 記号に続く部分です。

hashchange イベントは、ハッシュが変更された際に発生します。

記述例
<span id="a"></span><span id="b"></span><span id="c"></span>
<div id="d"></div>
<div id="h"></div>

<script>
function dispEvent(event) {
  event.preventDefault();    // デフォルトの処理を行わない
  document.getElementById("d").textContent = event.type;
  document.getElementById("h").textContent = this.location.hash;
}
window.addEventListener('hashchange', dispEvent, false);
</script>

<a href="#a">a</a><br>
<a href="#b">b</a><br>
<a href="#c">c</a>

a や b、c をクリックしてください。ハッシュが変わりますので hashchange イベントが発生し、ハッシュが表示されます。

実行例

(5) スクロール(scroll)

scroll イベントは、要素の内容がスクロールバーによってスクロールされたとき発生します。

記述例
<div id="d"></div>

<script>
function clear() {
  document.getElementById("d").textContent="";
}
function dispEvent(event) {
  document.getElementById("d").textContent=event.type;
}
var w = this.parent;    // window オブジェクト
w.addEventListener('mouseout', clear, false);
w.addEventListener('scroll', dispEvent, false);
</script>

スクロールバーをクリックする、マウスのホイールを回転させるなどしてスクロールさせてください。scroll イベントが発生します。

実行例

(6) エラー(error)

error イベントは、実行しようとした関数が定義されていないなどのとき発生します。

記述例
<div id="d"></div>
<script>
function dispEvent(event) {
  document.getElementById("d").textContent=event.type;
}
window.addEventListener('error', dispEvent, false);
func();               // ここでエラーが発生する
</script>

実行しようとした関数 func が定義されていないので error イベントが発生します。

実行例 (「実行例」をクリックしてください。別ウィンドウで開きます)


10.3.4  フォーム・イベント

フォーム内のアクションにより起動されるイベントです。

イベント説明イベントが発生する主な要素イベントオブジェクト
blur要素がフォーカスを失ったときに発生するイベントwindow、body 要素内の要素FocusEvent
change要素が変更されたときに発生するイベントinput、select、textareaEvent
focus要素にフォーカスが当ったときに発生するイベントwindow、body 要素内の要素FocusEvent
input要素にユーザ入力があったときに発生するイベントinput、textarea などInputEvent
invalidフォームの送信に失敗した場合に発生するイベントinputEvent
resetフォームをリセットしたときに発生するイベントformEvent
search検索要素(<input type="search">)に入力されたときに発生するイベントinput(search)Event×
select要素内の文字列が選択されたときに発生するイベントinput、textareaUIEvent
submitフォームを送信したときに発生するイベントformEvent

(1) フォーカス(focus、blur)

focus イベントは要素が選択された際に発生します。

blur イベントは他の要素が選択されるなどして、現在の要素からフォーカスが外れた際に発生します。

記述例
<div id="d"></div>

<script>
window.addEventListener('focus', function() {document.getElementById("d").textContent='focus'}, false);
window.addEventListener('blur', function() {document.getElementById("d").textContent='blur'}, false);
</script>

下の入力欄の中をクリックしてみてください。focus イベントが発生し、focus という文字が表示されています。

下の入力欄の外をクリックしてみてください。blur イベントが発生し、blur という文字が表示されています。

実行例

(2) 入力(input、change、search、select)

input イベントは入力欄に何かを入れたら(文字を消しても)発生します。

change イベントは入力欄を変更した後、その入力欄を抜けたとき発生します。また、select 要素では入力欄を抜けなくても発生します。

search イベントは <input tyle="search">で [Enter]キーを押したとき、あるいは(もしあれば)× をクリックしたときに発生します。ただし、 では発生しません。

select イベントは入力されている文字列を選択(マウスの左ボタンを押しながら文字列上をドラッグ)したときに発生します。

記述例
<div id="d"></div>
<input id="text" type="text"><br>
<input id="search" type="search"><br>
<select id="select">
  <option value="0"></option>
  <option value="1" label="aaa">aaa</option>
  <option value="2" label="bbb">bbb</option>
  <option value="3" label="ccc">ccc</option>
</select>
  
<script>
function clear() {
  document.getElementById("d1").textContent="";
  document.getElementById("text").value="";
  document.getElementById("search").value="";
  document.getElementById("select").value="";
}
function dispEvent(event) {
  document.getElementById("d1").textContent+=event.type + " ";
}
document.body.addEventListener('mouseleave', clear, false);
var tx = document.getElementById("text");
tx.addEventListener('input', dispEvent, false);
tx.addEventListener('change', dispEvent, false);
tx.addEventListener('select', dispEvent, false);
var sc = document.getElementById("search");
sc.addEventListener('input', dispEvent, false);
sc.addEventListener('change', dispEvent, false);
sc.addEventListener('search', dispEvent, false);
sc.addEventListener('select', dispEvent, false);
var sl = document.getElementById("select");
sl.addEventListener('input', dispEvent, false);
sl.addEventListener('change', dispEvent, false);
</script>

下の入力欄に何か文字を入力してみてください。input イベントが発生し、input という文字が表示されています。

その後、他の入力欄に移ると change イベントが発生し、change という文字が表示されています。select 要素で選択しても発生します。

search と書かれた欄は検索用の入力欄です。ここに何か入力して [Enter]キーを押すと search イベントが発生し、search という文字が表示されています。

また、入力された文字列を選択(マウスの左ボタンを押しながら文字列上をドラッグ)すると select イベントが発生し、select という文字が表示されています。

実行例

(3) 不正入力(invalid)

invalid イベントは type 属性に合わない入力がされ、フォームが送信されたときに発生します。invalid イベントが発生する type 属性は url や email です。

記述例
<div id="d"></div>
<input id="t" type="email" value="EMAIL">
<input type="submit" value="送信">
<script>
function clear() {
  document.getElementById("d1").textContent="";
  document.getElementById("t").value="EMAIL";
}
function dispEvent(event) {
  document.getElementById("d1").textContent+=event.type + " ";
}
document.body.addEventListener('mouseleave', clear, false);
var t = document.getElementById("t");
t.addEventListener('invalid', dispEvent, false);
</script>

email の入力は、アットマーク( @ )を含む妥当なメールアドレスでなければ invalid イベントが発生します。

実行例

(4) ボタン(submit、reset)

submit イベントは submit ボタンがクリックされ、フォームが送信されたときに発生します。

reset イベントは reset ボタンがクリックされ、フォームの入力が初期状態に戻されたときに発生します。

記述例
<div id="d"></div>
<form id="f" action="#">
<input type="submit" value="送信"> <input type="reset" value="リセット">
</form>
<script>
function clear() {
  document.getElementById("d1").textContent="";
}
function dispEvent(event) {
  document.getElementById("d1").textContent+=event.type;
}
document.body.addEventListener('mouseleave', clear, false);
var f = document.getElementById("f");
f.addEventListener('submit', dispEvent, false);
f.addEventListener('reset', dispEvent, false);
</script>
実行例

10.3.5  ドラッグ・イベント

ドラッグによって起動されるイベントです。

イベント説明イベントが発生する主な要素イベントオブジェクト
drag要素をドラッグしたときに発生するイベントbody 要素内の要素DragEvent
dragendドラッグ操作の最後に発生するイベントbody 要素内の要素
dragenter要素が有効なドロップ目標にドラッグされたときに発生するイベントbody 要素内の要素
dragleave要素が有効なドロップ目標から離れたときに発生するイベントbody 要素内の要素
dragover要素が有効なドロップ目標の上にドラッグされているときに発生するイベントbody 要素内の要素
dragstartドラッグ操作を開始したときに発生するイベントbody 要素内の要素
dropドラッグした要素をドロップしたときに発生するイベントbody 要素内の要素

ドラッグ中に発生するイベントを表示します。

記述例
スタイルシート
 <style>
  span.src {
    color:orange;
  }
  span.dst {
    color:green;
  }
</style>
  
ボディ
<div id="d"></div>
<img id="e" src="figures/bear.png" width="74" height="74">
<img id="x" style="border:solid 1px gray;width:100px;height:100px;">
<script>
var dragCount = 0;
var dragoverCount = 0;
function clear() {
  dragCount = 0;
  dragoverCount = 0;
  d.innerHTML = "";
  x.src = "";
}
function getEventTrace(str, style, count) {
  if (count == undefined)
    return "<span class='" + style + "'>" + str + "</span> ";
  else
    return "<span class='" + style + "'>" + str + "(" + count + ") </span> ";
}
function dispEvent(event, style) {
  if (event.type == "drag") {
    if (++dragCount > 1) {
      var s = d.innerHTML;
      var n = s.lastIndexOf("(");
      d.innerHTML = getEventTrace(s.substring(0, n), style, dragCount);
    }
    else {
      d.innerHTML += getEventTrace(event.type, style, 1);
    }
  }
  else if (event.type == "dragover") {
    if (++dragoverCount > 1) {
      var s = d.innerHTML;
      var n = s.lastIndexOf("(");
      d.innerHTML = getEventTrace(s.substring(0, n), style, dragoverCount);
    }
    else {
      d.innerHTML += getEventTrace(event.type, style, 1);
    }
  }
  else {
    dragCount = 0;
    event = 0;
    document.getElementById("d").innerHTML += getEventTrace(event.type, style);
  }
}
var d = document.getElementById("d");
var e = document.getElementById("e");
var x = document.getElementById("x");
e.addEventListener('drag', function() {dispEvent(event, "src");}, false);
e.addEventListener('dragstart', function() {clear();dispEvent(event, "src");}, false);
e.addEventListener('dragend', function() {dispEvent(event, "src");}, false);
x.addEventListener('drag', function() {dispEvent(event, "dst");}, false);
x.addEventListener('dragenter', function() {dispEvent(event, "dst");}, false);
x.addEventListener('dragover', function() {dispEvent(event, "dst");}, false);
x.addEventListener('dragleave', function() {dispEvent(eventt, "dst");}, false);
x.addEventListener('dragexit', function() {dispEvent(event, "dst");}, false);
x.addEventListener('drop', function() {dispEvent(event, "dst");x.src="bear.png";}, false);
</script>

熊の絵をドラッグして右側の四角の中でマウスボタンを離してください。ドラッグ中に発生するイベントが表示されます。

ドラッグ元では、dragstartdrag ... dragdragend の順に、ドラッグ先では、dragenterdragover ... dragoverdragleave の順に発生します(ただし、drag は移動するたびに発生しますので発生回数を表示するようにしています)。

実行例(ドラッグ)

上記の例では、ドロップはできません。ドロップできるようにするためには、dragover イベントをキャンセルする(デフォルトの動作をやめる)必要があります。

ドロップしたときに発生するイベントを表示します。

記述例
スタイルシート
<style>
  span.src {
    color:orange;
  }
  span.dst {
    color:green;
  }
</style>

ボディ
<div id="d"></div>
<img id="e" src="figures/bear.png" width="74" height="74">
<img id="x" style="border:solid 1px gray;width:100px;height:100px;">
<script>
var dragCount = 0;
var dragoverCount = 0;
function clear() {
  dragCount = 0;
  dragoverCount = 0;
  d.innerHTML = "";
  x.src = "";
}
function getEventTrace(str, style, count) {
  if (count == undefined)
    return "<span class='" + style + "'>" + str + "</span> ";
  else
    return "<span class='" + style + "'>" + str + "(" + count + ") </span> ";
}
function dispEvent(event, style) {
  if (event.type == "drag") {
    if (++dragCount > 1) {
      var s = d.innerHTML;
      var n = s.lastIndexOf("(");
      d.innerHTML = getEventTrace(s.substring(0, n), style, dragCount);
    }
    else {
      d.innerHTML += getEventTrace(event.type, style, 1);
    }
  }
  else {
    dragCount = 0;
    dragoverCount = 0;
    document.getElementById("d").innerHTML += getEventTrace(event.type, style);
  }
}
var d = document.getElementById("d");
var e = document.getElementById("e");
var x = document.getElementById("x");
e.addEventListener('drag', function() {dispEvent(event, "src");}, false);
e.addEventListener('dragstart', function() {clear();dispEvent(event, "src");}, false);
e.addEventListener('dragend', function() {dispEvent(event, "src");}, false);
x.addEventListener('drag', function() {dispEvent(event, "dst");}, false);
x.addEventListener('dragenter', function() {dispEvent(event, "dst");}, false);
x.addEventListener('dragover', function() {event.preventDefault();}, false);         // <-- ここを変えている
x.addEventListener('dragleave', function() {dispEvent(event, "dst");}, false);
x.addEventListener('dragexit', function() {dispEvent(event, "dst");}, false);
x.addEventListener('drop', function() {dispEvent(event, "dst");x.src="bear.png";}, false);     // ドロップ先に熊の絵を表示
</script>

熊の絵をドラッグして右側の四角の中でマウスボタンを離してください。ドラッグ中に発生するイベントが表示されます。

ドロップ先では、dragenterdrop の順に発生します。

なお、この例では、ドロップした後に右側の四角の中に熊の絵が表示されますが、これは自動的に行われるのではなく、drop イベントが発生したときに javascript で表示するようにしています。

実行例(ドロップ)


10.3.6  クリップボード・イベント

コピー & ペーストなどによって起動されるイベントです。

イベント説明イベントが発生する主な要素イベントオブジェクト
copyコピーしたときに発生するイベントbody 要素内の要素ClipboardEvent
cutカットしたときに発生するイベントbody 要素内の要素
pasteペースト(貼り付け)したときに発生するイベントbody 要素内の要素
記述例
<div id="d"></div>
<span id="s">ABCDE漢字01234</span><br>
<input id="t" type="text">

<script>
function dispEvent(event) {
  document.getElementById("d").textContent=event.type;
}
var s = document.getElementById("s");
var t = document.getElementById("t");
s.addEventListener('copy', dispEvent, false);
t.addEventListener('copy', dispEvent, false);
t.addEventListener('cut', dispEvent, false);
t.addEventListener('paste', dispEvent, false);
</script>

入力欄の中で、文字列のコピー(Ctrl+C)や貼り付け(Ctrl+V)をしてみてください。発生したイベントが表示されます。

実行例

10.3.7  印刷・イベント

印刷、プレビューなどによって起動されるイベントです。

イベント説明イベントが発生する主な要素イベントオブジェクト
afterprint文書が印刷された後に発生するイベントwindowEvent
beforeprint文書が印刷される前に発生するイベントwindow
記述例
<div id="d"></div>

<script>
window.addEventListener('beforeprint', function() {document.getElementById("d").textContent='beforeprint'}, false);
window.addEventListener('afterprint', function() {document.getElementById("d").textContent='afterprint'}, false);
</script>

beforeprint イベント発生ときに beforeprint と表示します。[印刷]ボタンをクリックしてください。beforeprint イベントが発生しますが、そのそのあとすぐに afterprint イベントが発生してしまいますので、この例では alert を実行して、その間止めています。beforeprint と表示されていることを確認してください。

[印刷]ボタンでは window.print() を実行していますが、印刷ダイアログが表示された時点で afterprint イベントが発生し afterprint と表示されます。

実行例

10.3.8  メディア・イベント

動画、画像やオーディオのようなメディアにより起動されるイベントです。

イベント説明イベントが発生する主な要素イベントオブジェクト
canplayファイルの再生開始準備(開始するのに十分なバッファリングが)ができたときに発生するイベントvideo、audio 要素Event
canplaythroughバッファリングのために中断しないで、終了までずっとファイルを再生することができる場合に発生するイベントvideo、audio 要素
durationchangeメディアの長さが変わったときに発生するイベント
emptied何らかの問題が発生して、(予期しない切断のように)ファイルが突然使用できなくなったときに発生するイベントvideo、audio 要素
endedメディアが終了したときに発生するイベントvideo、audio 要素
errorファイルのロード中にエラーが発生したときに発生するイベント
loadeddataメディアデータがロードされたときに発生するイベントvideo、audio 要素
loadedmetadataメタデータ(大きさと演奏時間など)がロードされるときに発生するイベントvideo、audio 要素
loadstart実際にロードが始まるちょうどそのときに発生するイベントvideo、audio 要素
pauseメディアデータがユーザかプログラムのいずれかによって一時休止されたときに発生するイベントvideo、audio 要素
playメディア再生開始の準備ができたときに発生するイベントvideo、audio 要素
playingメディアが実際に再生開始されたときに発生するイベントvideo、audio 要素
progressブラウザがメディアデータを取得しているときに実行するスクリプトvideo、audio 要素
ratechange再生速度を変更する(ユーザがスローモーションや早送りモードに切替ええる)たびに発生するイベント
readystatechangeレディ状態の変化のたびに発生するイベント(Ready状態は、メディアデータの状態を追跡する)
seekedseeking 属性に、シークが終了したことを示す false が設定されたときに発生するイベントvideo、audio 要素
seekingseeking 属性に、シーク中であることを示す true が設定されているときに発生するイベントvideo、audio 要素
stalledブラウザが何らかの理由でメディアのデータをフェッチできない場合に発生するイベント
suspend何らかの理由でロードが完了する前にメディアデータのフェッチが停止したときに発生するイベント
timeupdate再生位置が変更されたときに発生するイベント(通常の再生で繰り返し発生する)video、audio 要素
volumechangeボリュームが変更されるたびに発生するイベント(ボリュームを "mute" へ設定など)video、audio 要素
waitingメディアは一時停止したが、再開が予想されるときに発生するイベント(メディアが多くのデータをバッファリングして一時停止したときなど)
記述例
<video id="v" controls src="xxxxx.mp4" width="240" height="120"></video>  <div class="switch" onclick="restart();">再実行</div>
<br>
<table>
<tr><td class="note" style="white-space:nowrap;vertical-align:top;">イベント → </td>
    <td><div id="d" style="height:80px;overflow:auto;"></div></td></tr>
</table>
<script>
function restart() {
  document.getElementById("d").textContent = "";
  document.getElementById("v").src = "xxxxx.mp4";
}
var cnt = 0;
var pre = "";
function dispEvent(event) {
  if (event.type == "timeupdate") {
    if (++cnt > 1) {
      var s = document.getElementById("d").textContent;
      var n = s.lastIndexOf("(");
      document.getElementById("d").textContent = s.substring(0, n) + "(" + cnt + ") ";
    }
    else {
      document.getElementById("d").textContent += event.type + "(1) ";
    }
  }
  else {
    cnt = 0;
    document.getElementById("d").textContent += event.type + " ";
  }
}
var v = document.getElementById("v");
v.addEventListener('emptied', dispEvent, false);
v.addEventListener('canplay', dispEvent, false);
v.addEventListener('canplaythrough', dispEvent, false);
v.addEventListener('play', dispEvent, false);
v.addEventListener('playing', dispEvent, false);
v.addEventListener('progress', dispEvent, false);
v.addEventListener('waiting', dispEvent, false);
v.addEventListener('loadstart', dispEvent, false);
v.addEventListener('loadeddata', dispEvent, false);
v.addEventListener('loadedmetadata', dispEvent, false);
v.addEventListener('ended', dispEvent, false);
v.addEventListener('pause', dispEvent, false);
v.addEventListener('timeupdate', dispEvent, false);
v.addEventListener('volumechange', dispEvent, false);
v.addEventListener('seeked', dispEvent, false);
v.addEventListener('seeking', dispEvent, false);
v.addEventListener('readystatechange', dispEvent, false);
</script>

また、同じイベントが連続して発生するような場合は、カッコ内に発生した回数を表示しています。

実行例

10.3.9  アニメーション・イベント

アニメーションなどによって起動されるイベントです。

イベント説明イベントが発生する主な要素イベントオブジェクト
animationendスタイルシートのアニメーションが完了した後に発生するイベントbody 要素内の要素AnimationEvent
animationiterationスタイルシートのアニメーションが繰り返されたときに発生するイベントbody 要素内の要素
animationstartスタイルシートのアニメーションが開始された後に発生するイベントbody 要素内の要素

では、スタイルシートの属性名の最初に -webkit- を付け(例:-webkit-animation-name)、イベント名は 最初に webkit を付けて単語の区切りを大文字にする(例:webkitAnimationStart)必要があります。

記述例
スタイルシート
@keyframes anime {
  from {width: 50px; height: 50px; background-color: aqua;}
  to {width: 200px; height: 50px; background-color: lightgreen;}
}
div.anim {
  animation-iteration-count:3;
  animation-duration:5s;
}

ボディ
<div id="d"></div>
<div id="a" class="anim" style="animation-name:anime;" onclick="location.reload();">アニメーション</div>
<script>
function dispEvent(event) {
  document.getElementById("d").textContent=event.type;
}
var a = document.getElementById("a");
a.addEventListener('animationstart', dispEvent, false);
a.addEventListener('animationiteration', dispEvent, false);
a.addEventListener('animationend', dispEvent, false);
</script>

四角の幅が広く(色も水色から薄い緑に)なっていくというアニメーションを3回繰り返しています。

アニメーションの開始ときに animationstart イベントが発生し animationstart と表示します。

アニメーションの繰り返しのときには animationiteration イベントが発生し animationiteration と表示します。

そして、アニメーションが終わったときには animationend イベントが発生し animationend と表示します。

アニメーションをもう一度開始したいときには、"アニメーション"をクリックしてください。

実行例


10.3.10  サーバー送信・イベント

サーバーへの送信などによって起動されるイベントです。

イベント説明イベントが発生する
主な要素
イベント
オブジェクト
abortリクエストが中断して失敗しときに発生するイベントXMLHTTPRequestProgressEvent
errorリクエストに失敗したときに発生するイベント
loadリクエストが終了したときに発生するイベント
loadend失敗か成功かにかかわらずリクエストが終了したときに発生するイベント
loadstartリクエストが開始したときに発生するイベント
progressデータの受信中に発生するイベント
readystatechangeXMLHttpRequest の readyState の値が変わったときに発生するイベント
状態説明
0UNSENTクライアントは作成済み。open() はまだ呼ばれていない。
1OPENEDopen() が呼び出し済み。
2HEADERS_RECEIVEDsend() が呼び出し済みで、ヘッダーとステータスが利用可能。
3LOADINGダウンロード中。responseText には部分データが入っている。
4DONE操作が完了した。
timeoutタイムアウトしたときに発生するイベント

readystatechange イベントは、readyState プロパティの状態が変わるたびに発生します。

記述例
<span id="d11"></span><span id="d12"></span> <!-- 略 --> <br>

<!-- 以下略 -->


<script>
var xhr = new XMLHttpRequest();  // HTTPでファイルを読み込むためのXMLHttpRxhruestオブジェクトを生成
var m = 1;
xhr.addEventListener('readystatechange', dispEvent, false);
dispEvent();    // open 前
xhr.open("get", "sample.txt", true); // アクセスするファイルを指定
xhr.send();

function dispEvent() {
  document.getElementById("d1" + m).textContent = xhr.status;
  document.getElementById("d2" + m).textContent = xhr.statusText;
  document.getElementById("d3" + m).textContent = xhr.readyState;
  document.getElementById("d4" + m).textContent = xhr.responseText;
  m++;
}
</script>
実行例

成功しても失敗しても通信終了時には load や loadend イベントが発生します。

XMLHttpRxhruest としてはサーバーから何かしら結果が返ってきたならば「通信成功」とみなしているということです。

XMLHttpRxhruest の失敗というのはサーバーが応答しないとか何も返ってこないとかいう場合を指します。

記述例(正常終了)
<span id="d1"></span><span id="d2"></span> <!-- 略 --> <br>

<script>
var xhr = new XMLHttpRequest();  // HTTPでファイルを読み込むためのXMLHttpRxhruestオブジェクトを生成

var n = 1;
xhr.addEventListener('load', function(){document.getElementById("d" + n++).textContent = "load";}, false);
xhr.addEventListener('loadstart', function(){document.getElementById("d" + n++).textContent = "loadstart";}, false);
xhr.addEventListener('loadend', function(){document.getElementById("d" + n++).textContent = "loadend(" + xhr.status + ")";}, false);
xhr.addEventListener('progress', function(){document.getElementById("d" + n++).textContent = "progress";}, false);
xhr.addEventListener('timeout', function(){document.getElementById("d" + n++).textContent = "timeout";}, false);
xhr.addEventListener('abort', function(){document.getElementById("d" + n++).textContent = "abort";}, false);
xhr.addEventListener('error', function(){document.getElementById("d" + n++).textContent = "error";}, false);

xhr.open("get", "sample.txt", true); // アクセスするファイルを指定
xhr.send();
</script>
記述例(異常終了)
xhr.open("get", "XXXXX.txt", true); // アクセスするファイルがない
xhr.send();
記述例(中断)
xhr.open("get", "sample.txt", true);
xhr.send();
xhr.abort();    // 中断
記述例(タイムアウト)
xhr.open("get", "http://unknown", true);
xhr.timeout = 1;    // タイムアウト時間(1ミリ秒)
xhr.send();
記述例(エラー)
xhr.open("get", "xxx://", true);    // 不正プロトコル
xhr.send();
実行例

10.3.11  タッチ・イベント

タッチなどによって起動されるイベントです。

イベント説明イベントが発生する主な要素イベントオブジェクト
touchcancelタッチが中断されたときに発生するイベントbody 要素内の要素TouchEvent
touchendタッチが終了した(スクリーンから指が離れた)ときに発生するイベントbody 要素内の要素
touchmoveスクリーンに触れている指が動いたときに発生するイベントbody 要素内の要素
touchstartタッチが開始された(スクリーンに指が触れた)ときに発生するイベントbody 要素内の要素
記述例
<div id="d"></div>

<script>
var touchmoveCount = 0;
function clear() {
  touchmoveCount = 0;
  document.getElementById("d").textContent = "";
}
function dispEvent(event) {
  event.preventDefault();    // デフォルトの処理を行わない
  if (event.type == "touchmove") {
    if (++touchmoveCount > 1) {
      var s = document.getElementById("d").textContent;
      var n = s.lastIndexOf("(");
      document.getElementById("d").textContent = s.substring(0, n) + "(" + touchmoveCount + ") ";
    }
    else {
      document.getElementById("d").textContent += event.type + "(1) ";
    }
  }
  else {
    touchmoveCount = 0;
    document.getElementById("d").textContent += event.type + " ";
  }
}
document.body.addEventListener('mouseleave', clear, false);
var e = document.getElementById("e");
e.addEventListener('touchstart', dispEvent, false);
e.addEventListener('touchmove', dispEvent, false);
e.addEventListener('touchend', dispEvent, false);
e.addEventListener('touchcancel', dispEvent, false);
</script>

四角の中をタッチしてみてください。(ただし、もちろんタッチパネルで)

touchstart → touchmove ... touchmove → touchend の順に発生します(ただし、touchmove は移動するたびに発生しますので発生回数を表示するようにしています)。

実行例

10.3.12  その他・イベント

その他のイベントです。

イベント説明イベントが発生する主な要素イベントオブジェクト
messageメッセージがウインドウに送られてくると発生するイベントwindowMessageEvent
offlineネットワークがオフラインになったときに発生するイベントwindowEvent
onlineネットワークがオンラインになったときに発生するイベントwindowEvent
popstateウィンドウの履歴が変更されたときに発生するイベントwindowPopStateEvent××××
storageWeb ストレージ領域が更新されたときに発生するイベントStorageEvent

(1) メッセージ(message)

message イベントは、別ウィンドウからメッセージを伝達された際に発生します。

記述例
<iframe src="other.htm" id="other" frameborder="1px" width="600px" height="40px"></iframe>
<script>
var d = new Date();
var iframe = document.getElementById('other');
iframe.contentWindow.postMessage("処理完了(" + d.toLocaleString() + ")", "/");   // メッセージ送信
</script>
other.htm
<div id="d"></div>
<div id="t"></div>

<script>
window.addEventListener('message', function(event){
  document.getElementById("d").textContent = event.type;   // イベントの種類
  document.getElementById("t").textContent = event.data;   // 受信メッセージ
});
</script>

メッセージを入力して「送信」ボタンをクリックしてください。iframe 内の HTML にメッセージが伝達されます。伝達された側には message イベントが発生し、伝達されたメッセージが表示されます。

実行例

(2) オンライン(online、offline)

online イベント発生ときに online と表示します。また、offline イベント発生ときに offline と表示します。

ただし、イベントが発生しているかどうかはよく分かりません。

記述例
<div id="d"></div>

<script>
window.addEventListener('online', function() {document.getElementById("d").textContent='online'}, false);
window.addEventListener('offline', function() {document.getElementById("d").textContent='offline'}, false);
</script>
実行例

(3) 履歴(popstate)

popstate イベントは、ブラウザの [戻る] や [進む] ボタンを使った場合に発生します。

また、history.back() や history.forward() でも同様に発生します。

記述例
<div id="d"></div>

<script>
history.pushState("aaaaa", null, null);
window.addEventListener('popstate', function(e){
  var d = new Date(e.timeStamp);
  document.getElementById('d').textContent = e.type + " " + d.toLocaleString();
});
</script>

「ヒストリ 2」で、ブラウザの [戻る] ボタンをクリックしたときに popstate イベントが発生し、イベント名と発生日時が表示されます。

実行例 (別ウィンドウで開きます)

ただし、 では、イベントが発生せず、 では、e.timeStamp が正しく設定されていないようです。

10.4  イベントオブジェクト

イベントオブジェクトは、イベントが起きたときに呼び出されるメソッド(イベントリスナー)に最初の引数として渡されます。もし参照の必要がなければ、引数を記述しなくても構いません。

function foo(event) {
  // event引数はイベントオブジェクトを自動的に割り当てられます
  alert(event);
}
button.onclick = foo;

ただし、イベントオブジェクトは、発生したイベントの種類ごとに異なり、含まれる情報が違います。これらのイベントオブジェクトは Event から派生しているか、あるいは Event から派生したイベントオブジェクトから派生しています。

Event オブジェクトと Event オブジェクトを継承している、主なイベントオブジェクトには次のようなものがあります。

イベントオブジェクト使用するイベント
Event
AnimationEventanimationstart、animationiteration、animationend
BeforeUnloadEventbeforeunload
ClipboardEventcut、copy、paste
DragEventdrag、dragend、dragenter、dragexit、dragleave、dragover、dragstart、drop
FocusEventfocus、blur、focusin、focusout
KeyboardEventkeydown、keypress、keyup
MessageEventmessage
MouseEventclick、dblclick、mouseup、mousedown
PageTransitionEventpagehide、pageshow××××××
TouchEventtouchcancel、touchend、touchmove、touchstart
UIEventabort、error、load、resize、scroll、select、unload
WheelEventmousewheel×
ProgressEventprogress、loadend

主なイベントオブジェクトの継承関係を次に示します。

10.4.1  Event

発生したイベントに引数として渡されるイベントオブジェクトは、Event オブジェクトを継承しています。


(1) プロパティ

Event オブジェクトには次のような属性が含まれています。

プロパティ
bubblesR/Oイベントがバブリング(親要素に向かって伝播)するかどうか (true:バブリングする、false:しない)
cancelableR/Oイベントがキャンセルできるかどうか (true:できる、false:できない)
currentTargetR/Oイベントを処理した(イベントハンドラが実行された)オブジェクトへの参照
defaultPreventedR/Oevent.preventDefault() がイベントで呼ばれたかどうか (true:呼ばれた、false:呼ばれていない)
eventPhaseR/Oイベントが発生したフェーズ
フェーズ意味
Event.CAPTURING_PHASE1Capture フェーズ
Event.AT_TARGET2Target フェーズ
Event.BUBBLING_PHASE3Bubbling フェーズ
isTrustedR/Oイベントがブラウザによって開始されたかどうか (true:ブラウザ、false:スクリプト)
targetR/Oイベントを発生したオブジェクトへの参照
timeStampR/Oイベントが発生した日時××××××
typeR/Oイベントの名前
viewR/Oイベントが発生した window オブジェクト

フェーズやイベントの伝播については、「10.2  イベントの伝播」を参照してください。


記述例
<title>Event</title>
<!-- 途中略 -->

<form id="f">
  <input id="t" type="text" size="5">
</form>
<br>
<span id="d11"></span> <span id="d21"></span>
<!-- 以下略 -->

<script>
function clear() {
  for (let i = 1 ; i != 3 ; i++) {
    for (let j = 1 ; j != 8 ; j++) {
      document.getElementById("d" + i + j).textContent="";
    }
  }
  t.style.backgroundColor = "white";
}
function focus1(event) {
  focus(event, 1);
}
function focus2(event) {
  focus(event, 2);
}
function focus(event, n) {
  event.target.style.backgroundColor = "pink";
  document.getElementById("d" + n + "0").textContent=event.type;
  document.getElementById("d" + n + "1").textContent=event.target.tagName + " id=" + event.target.id;
  document.getElementById("d" + n + "2").textContent=event.currentTarget.tagName + " id=" + event.currentTarget.id;
  document.getElementById("d" + n + "3").textContent=event.eventPhase;
  document.getElementById("d" + n + "4").textContent=event.bubbles;
  document.getElementById("d" + n + "5").textContent=event.cancelable;
  document.getElementById("d" + n + "6").textContent=event.defaultPrevented;
  document.getElementById("d" + n + "7").textContent=event.isTrusted;
  let d = new Date(event.timeStamp);
  document.getElementById("d" + n + "8").textContent=d.toLocaleString();
  document.getElementById("d" + n + "9").textContent=event.view.document.title;
}

var t = document.getElementById("t");
var f = document.getElementById("f");
t.addEventListener('blur', clear, false);
t.addEventListener('focus', focus1, false);  // Target  フェーズ(イベントが発生したオブジェクトのみ)
f.addEventListener('focus', focus2, true);   // Capture フェーズ(Document からイベント発生オブジェクトに向かって順にイベントが発生する)
</script>

input 要素と form 要素のそれぞれでイベントハンドラーが設定されています。

下の例の入力欄(input 要素)をクリックしてみてください。そうすると、input 要素に focus イベントが発生します。

input 要素と form 要素のそれぞれで得られたイベントオブジェクトを表示します。

なお、currentTarget はイベントを処理した要素とその id を表示しています。

また、view は イベントが発生した window オブジェクトですが、ここでは、その document の title を表示しています。

実行例

(2) インスタンス生成

Event のインスタンスを生成します。

Event 以外のインスタンス生成については、MouseEvent のみ記述しています。

new Event(type[,init])

Event インスタンスを生成する。

引数 type:イベント名

引数 init:初期値マップ  形式({ "key":true/false, ... })

key意味
bubblesイベントの伝播方向(true:先祖方向、false:子孫方向)(規定値:false)
cancelablepreventDefault() によるキャンセルを可能にするかどうか(true:可、false:不可)(規定値:false)
composedshadow DOM と通常の DOM 間でイベントが伝播できるかどうか(true:可、false:不可)(規定値:false)

戻り値:Event インスタンス


「クリック」ボタンがクリックされると、イベントを生成して、input 要素に送信します。

記述例
<input id="text1" type="text" size="10"> <input id="text2" type="text" size="10">
 <div class="switch" onclick="fire();">クリック</div>

<script>
var t1 = document.getElementById("text1");
var t2 = document.getElementById("text2");
t1.addEventListener("focus", setDate);    // focus イベントが発生すると、setDate() を呼び出す
t2.addEventListener("focus", setTime);    // focus イベントが発生すると、setTime() を呼び出す

function fire() {
  var evt = new Event("focus", {"bubbles":true, "cancelable":true});
  t1.dispatchEvent(evt); // focus イベントを発生させる
  t2.dispatchEvent(evt); // focus イベントを発生させる
}
function setDate() {
  var dt = new Date();
  this.value = dt.toLocaleDateString();
}
function setTime() {
  var dt = new Date();
  this.value = dt.toLocaleTimeString();
}
</script>

「クリック」ボタンをクリックしてください。

実行例

(3) メソッド

Event オブジェクトの主なメソッドについて説明します。Event から派生した他のイベントオブジェクトでも利用できます。

メソッド引数機能戻り値
initEvent(type, bubbles, cancelable)イベントの種類、イベントの伝播、キャンセル可イベントの設定をする。なし
stopPropagation()なしイベントの伝播を止める。なし
preventDefault()なしイベントの伝播を止めずに、そのイベントのデフォルトの動作をキャンセルする。なし

フェーズやイベントの伝播については、「10.2  イベントの伝播」を参照してください。


(3-1) initEvent

createEvent によって作成された event の値を設定します。

オブジェクト.initEvent(type[, bubbles[, cancelable]])

イベントの設定をする。(非推奨のメソッドとなっていますので、使用する場合は注意してください。)

引数 type:イベントの種類

イベントタイプイベントの種類
HTMLEventsload, unload, abort, error, select, change, submit, reset, focus, blur, resize, scroll
MouseEventsclick, mousedown, mouseup, mouseover, mouseup, mouseout
MutationEventsDOMSubtreeModified, DOMNodeInserted, DOMNodeRemoved, DOMNodeRemovedFromDocument, DOMNodeInsertedIntoDocument, DOMAttrModified, DOMCharacterDataModified
UIEventsDOMFocusIn, DOMFocusOut, DOMActivate

引数 bubbles:イベントを先祖要素に伝搬する(true)、伝播しない(false) 規定値

引数 cancelable:preventDefault() による、イベントのキャンセル可能にする(true)、可能にしない(false) 規定値

戻り値:なし

cancelable については、(3-3) preventDefault の例を参照してください。

記述例
<table>
<tr><td>
  <div id="dv" style="width:200px;">div<br>
    <span id="sp">span   <input id="ip" type="checkbox">input</span><br><br>
  </div>
</td><td>
  <span id="d01"></span><br>
  <span id="d02"></span><br>
</td></tr>
</table>

<script>
let d;
function input() { document.getElementById(d).textContent = "input "; }
function span() { document.getElementById(d).textContent += "span "; }
function div() { document.getElementById(d).textContent += "div "; }
document.getElementById("ip").addEventListener("click", input);
document.getElementById("sp").addEventListener("click", span);
document.getElementById("dv").addEventListener("click", div);

let evt01 = getEvent(true);     // 伝搬する
let evt02 = getEvent(false);    // 伝搬しない
d = "d01";
document.getElementById("ip").dispatchEvent(evt01);
d = "d02";
document.getElementById("ip").dispatchEvent(evt02);

document.getElementById("ip").removeEventListener("click", input);
document.getElementById("sp").removeEventListener("click", span);
document.getElementById("dv").removeEventListener("click", div);

function getEvent(bubbles) {
  let evt = document.createEvent("HTMLEvents");
  evt.initEvent("click", bubbles, true);
  return evt;
}
</script>

bubbles が true のときは、click イベントが先祖要素(span や div)にも伝搬します。false のときは、伝播しません。

実行例

(3-2) stopPropagation

同じイベントハンドラーを複数の要素に指定した場合、イベントはそれらの要素に対して順番に発生していきます。stopPropagation() は、そうしたイベントの伝播を停止して、それ以降への伝播をせき止めます。

オブジェクト.stopPropagation()

イベントの伝播を停止して、それ以降への伝播をせき止める。

戻り値:なし

例えば、div 要素で stopPropagation() をすると、focus イベントは div 要素でのみ処理され、それ以降の要素には伝播しません。

記述例
<label id="stop" style="display:block;">stopPropagation
<select id="s">
  <option value="div" label="div"></option>
  <option value="form" label="form"></option>
  <option value="input" label="input" selected></option>
</select>
</label>
<br>
  
<div id="d">
  <form id="f">
    <input id="t" type="text" size="5"> <span id="d11"></span> <span id="d12"></span> <span id="d13"></span>
  </form>
</div>
  
<script>
var n = 1;
function clear() {
  n = 1;
  document.getElementById("d11").textContent="";
  document.getElementById("d12").textContent="";
  document.getElementById("d13").textContent="";
  t.style.backgroundColor = "white";
}
function focus(element) {
  return function (event) {
    event.target.style.backgroundColor = "pink";
    document.getElementById("d1" + n++).textContent=element;
    if (document.getElementById("s").value == element)          // "s" は stopPropagation を選択する select 要素
      event.stopPropagation();    // イベントの伝播を止める
  }
}

var t = document.getElementById("t");    // input 要素
var f = document.getElementById("f");    // form 要素
var d = document.getElementById("d");    // div 要素
t.addEventListener('blur', clear, false);
t.addEventListener('focus', focus("input"), true);
f.addEventListener('focus', focus("form"), true);
d.addEventListener('focus', focus("div"), true);
</script>

<div> - <form> - <input> の順にイベントが伝播します。イベントの伝播を停止する要素を stopPropagation で指定して、下の入力欄をクリックしてください。入力欄の上にイベントを処理した要素名が表示されます。

実行例

(3-3) preventDefault

イベントの伝播を止めずに、そのイベントのデフォルトの動作をキャンセルします。

ただし、イベントの cancelable が true の場合のみ有効です。これは、new Event(サブクラスも含む)か、あるいは、createEvent でイベントを生成したときに設定できます。

オブジェクト.preventDefault()

イベントの伝播を止めずに、そのイベントのデフォルトの動作をキャンセルする。

戻り値:なし(ただし、dispatchEvent でイベントを発生させたときは、dispatchEvent の戻り値が false になる。)

記述例
<form id="f" name="f">
  <label id="l1" style="background-color:yellow;"><input id="c1" name="c" type="checkbox" value="1" checked> 1 </label>
  <label id="l2" style="background-color:cyan;"><input id="c2" name="c" type="checkbox" value="2"> 2 </label>
   <span id="d11"></span> <span id="d12"></span> <span id="d13"></span> <span id="d14"></span> <span id="d15"></span>
</form>
<script>
var n = 1;
function clear() {
  n = 1;
  document.getElementById("d11").textContent="";
  document.getElementById("d12").textContent="";
  document.getElementById("d13").textContent="";
  document.getElementById("d14").textContent="";
  document.getElementById("d15").textContent="";
}
function click1(event) {
  click(event, "input");
}
function click21(event) {
  click(event, "label");
}
function click22(event) {
  click(event, "label");
  event.preventDefault();         // デフォルトの動作をキャンセル(2 の方)
}
function click3(event) {
  click(event, "form");
}
var preTime = 0;
function click(event, element) {
  if (preTime <= event.timeStamp -100) {
    clear();
    preTime = event.timeStamp;
  }
  document.getElementById("d1" + n++).textContent=element;
}

var c1 = document.getElementById("c1");
var c2 = document.getElementById("c2");
var l1 = document.getElementById("l1");
var l2 = document.getElementById("l2");
var f = document.getElementById("f");
f.addEventListener('blur', clear, false);
c1.addEventListener('click', click1, true);
c2.addEventListener('click', click1, true);
l1.addEventListener('click', click21, true);
l2.addEventListener('click', click22, true);
f.addEventListener('click', click3, true);
</script>

チェックボックスをクリックした場合は、左側(1の方)は通常通りデフォルトの動作としてチェックの表示・非表示が変わります。右側(2の方)は preventDefault() を実行しているので、チェックの表示・非表示が変わりません。また、イベントは共に form → label → input の順に伝播します。

ただし、ラベル(1 や 2 が表示された部分)をクリックした場合は、ラベルとチェックボックスに対してイベントが(伝播して)発生します(チェックボックスをクリックした場合はチェックボックスにのみイベントが発生します)。したがって、イベントは form → label と form → label → input の順に伝播するはずですが、preventDefault() をラベルのイベントハンドラーで実行している 2 の方は、なぜかラベルに対してのみイベント form → label が発生します。

実行例

preventDefault() を実行すると、デフォルトの動作をキャンセルできません。cancelable が true か false かは関係なさそうです。

なお、は、生成したイベントを送ってもデフォルトの動作が行われませんが、チェックボックスを直接クリックすれば、preventDefault() を実行した方はチェックが付きませんので、preventDefault() が有効であることが分かります。

記述例
<input id="check01" type="checkbox">check01 <input id="check02" type="checkbox">check02<br>
<input id="check11" type="checkbox">check11 <input id="check12" type="checkbox">check12<br>

<script>
document.getElementById("check01").addEventListener("click", function(event){
  event.preventDefault();
});
document.getElementById("check11").addEventListener("click", function(event){
  event.preventDefault();
});
let evt01 = getEvent(true);     // cancelable true
let evt02 = getEvent(true);
let evt11 = getEvent(false);    // cancelable false
let evt12 = getEvent(false);
document.getElementById("check01").dispatchEvent(evt01);
document.getElementById("check02").dispatchEvent(evt02);
document.getElementById("check11").dispatchEvent(evt11);
document.getElementById("check12").dispatchEvent(evt12);

function getEvent(cancelable) {
  let evt;
  try {
    evt = new MouseEvent("click", {"cancelable":cancelable});  // Edge、Chrome、Firefox、Opera、Sleipnir 用
  }
  catch(x) {
    evt = document.createEvent("HTMLEvents");                  // internet explorer、 Safari 用
    evt.initEvent("click", true, cancelable);
  }
  return evt;
}
</script>
実行例

10.4.2  AnimationEvent

(1) プロパティ

プロパティ
animationNameR/Oスタイルシートの animation-name
elapsedTimeR/Oアニメーションにかかった時間(秒)

では、スタイルシートの属性名の最初に -webkit- を付け(例:-webkit-animation-name)、イベント名は 最初に webkit を付けて単語の区切りを大文字にする(例:webkitAnimationStart)必要があります。

記述例
スタイルシート
@keyframes anime {
  from {width: 50px; height: 50px; background-color: aqua;}
  to {width: 200px; height: 50px; background-color: lightgreen;}
}
div.anim {
  animation-iteration-count:3;
  animation-duration:5s;
}

ボディ
<div id="d1"></div>
<div id="d2"></div>
<div id="d3"></div>
<div id="a" class="anim" style="animation-name:anime;" onclick="location.reload();">アニメーション</div>
<script>
function anim(event) {
  document.getElementById("d1").textContent=event.type;
  document.getElementById("d2").textContent=event.animationName;
  document.getElementById("d3").textContent=event.elapsedTime;
}
var a = document.getElementById("a");
a.addEventListener('animationstart', anim, false);
a.addEventListener('animationiteration', anim, false);
a.addEventListener('animationend', anim, false);
</script>

"アニメーション" をクリックするとアニメーションが始まります。同じアニメーションを3回繰り返します。そして、その都度イベントオブジェクトを表示します。

実行例

10.4.3  BeforeUnloadEvent

beforeunload イベント発生時、イベントハンドラーに引き渡されるイベントオブジェクトです。Event オブジェクトを継承しています。

(1) プロパティ

BeforeUnloadEvent 固有のプロパティは次のようなものがあります。

プロパティ
returnValueダイアログに表示したいメッセージを設定する。×
記述例
<input id="t" type="text"><br><br>
<div class="switch" onclick="go();">go</div>
<script>
function message(event) {
  if (document.getElementById("t").value.length > 0) {  // なんらか入力されたら returnValue に設定する
    event.returnValue = document.getElementById("t").value;
  }
}
function go() {
  window.addEventListener('beforeunload', message, false);
  location.href='other.htm'
}
</script>

入力欄になんらかを入力し[go]ボタンをクリックすると、ではサイトを離れるかどうかを聞くダイアログが表示されません。

実行例

10.4.4  ClipboardEvent

cut、copy、paste イベント発生時、イベントハンドラーに引き渡されるイベントオブジェクトです。Event オブジェクトを継承しています。

ただし、 では DragEvent のイベントオブジェクトが引数として渡るようです。

(1) プロパティ

ClipboardEvent 固有のプロパティは次のようなものがあります。

プロパティ
clipboardDataR/Ocut と copy、paste 操作によって影響を受けた MIME タイプを含むデータを持つ DataTransfer オブジェクト

では DragEvent のイベントオブジェクトが引数として渡るようなので、下の例では引数に clipboardData がない場合には window.clipboardData を使用するようにしています。

記述例(copy イベント)
<span id="d">ここの文章はコピーできませんので、悪しからず。</span><br>
<input id="o" size="60">
<script>
function copy(event) {
  event.preventDefault();    // デフォルトの処理を行わない
  var clip = event.clipboardData;
  clip.setData("text", "コピーはダメ!");   // クリップボードに格納する
}
document.getElementById("d").addEventListener('copy', copy, false);
</script>

"ここの文章はコピーできませんので、悪しからず。"のどこかをコピー(Ctrl-C あるいは メニューの「コピー」)して、下の入力欄に貼り付け(Ctrl-V あるいは メニューの「貼り付け」)をしてください。copy イベントでクリップボードに"コピーはダメ!"を格納していますので、入力欄には"コピーはダメ!"が挿入されます。

実行例

記述例(paste イベント)
<input id="o" size="30"><br>
<span id="d"></span>
<script>
function paste(event) {
  event.preventDefault();    // デフォルトの処理を行わない
  var clip = event.clipboardData || window.clipboardData;      // IE は window
  document.getElementById("o").value = clip.getData("text");   // プレーンテキストをクリップボードから得る
  document.getElementById("d").textContent = (new Date()).toLocaleString();   // 日時
}
document.getElementById("o").addEventListener('paste', paste, false);
</script>

どこかの文字列をコピーして、下の入力欄を選択し貼り付け(Ctrl-V あるいは メニューの「貼り付け」)をしてください。paste イベントが発生し、入力欄にコピーした文字列が上書きされます。また、その下には貼り付けた日時が表示されます。

実行例

10.4.5  MessageEvent

message イベント発生時、イベントハンドラーに引き渡されるイベントオブジェクトです。Event オブジェクトを継承しています。

(1) プロパティ

MessageEvent 固有のプロパティは次のようなものがあります。

プロパティ
dataR/Oメッセージとして送られた、数値、文字列、真偽値、配列、Date などを含むオブジェクト
originR/Oデータ送信元のオリジン(URL のポート番号まで)
portsR/Oメッセージとともに送られた MessagePort オブジェクト の配列
sourceR/Oデータ送信元の window オブジェクト

[演算]ボタンがクリックされたら入力欄の数値を iframe 内に送ります。演算結果は iframe 内から直接書き換えています。

記述例
<title>message</title>
<!-- 略 -->

<input id="v1" type="number" size="5"> <span id="op"> </span> <input id="v2" type="number" size="5"> = <span id="ans"></span><br>
<br>
<div class="switch" onclick="send();">演算</div><br><br>
<iframe src="add.htm" id="add" frameborder="1px" width="600px" height="100px"></iframe>
<script>
function send() {
  var d = {a:document.getElementById("v1").value, b:document.getElementById("v2").value};
  var iframe = document.getElementById("add");
  iframe.contentWindow.postMessage(d, "/");    // iframe 内にメッセージ送信
}
</script>
add.htm
<div id="d1"></div>
<!-- 以下略 -->

<script>
window.addEventListener('message', function(event){
  document.getElementById("d1").textContent = event.data.a + " " + event.data.b;  // メッセージ
  document.getElementById("d2").textContent = event.origin;
  document.getElementById("d3").textContent = event.ports;
  document.getElementById("d4").textContent = event.source.document.title;
  // 演算結果をメッセージ送信元に書き込む
  var p = event.source.document;
  var v1 = parseFloat(event.data.a);
  p.getElementById("v1").value = v1;
  var v2 = parseFloat(event.data.b);
  p.getElementById("v2").value = v2;
  p.getElementById("op").textContent = "+";
  p.getElementById("ans").textContent = v1 + v2;
});
</script>

入力欄に数値を入力して[演算]ボタンをクリックしてください。入力した内容などが表示されます。また、演算結果などが入力欄の横に表示されます。

source にはメッセージ送信元の window オブジェクトが設定されます。この例では送信元の title 要素を表示しています。

実行例

上の例は、演算結果を source(メッセージの送信元)から得られた要素に直接書き込んでいましたが、次の例は、MessagePort で渡す方法で実現してみます。

記述例
<input id="v1" type="number" size="5"> <span id="op"> </span> <input id="v2" type="number" size="5"> = <span id="ans"></span><br>
<br>
<div class="switch" onclick="send();">演算</div><br><br>
<div id="d1"></div>
<div id="d2"></div>
<iframe src="add.htm" id="add" frameborder="1px" width="600px" height="40px"></iframe>
<script>
function send() {
  var d = {a:document.getElementById("v1").value, b:document.getElementById("v2").value};
  var iframe = document.getElementById("add");
  iframe.contentWindow.postMessage(d, "/");    // iframe 内にメッセージ送信
}
window.addEventListener('message', function(event){
  document.getElementById("d1").textContent = event.ports;
  document.getElementById("d2").textContent = event.source.document.title;

  var port = event.ports[0];  // iframe 側から送られてきたポート
  port.start();  // 受信可能にする
  // ポートに対して送られてきたメッセージを表示する
  port.addEventListener('message', function(event){
    document.getElementById("v1").value = event.data.v1;
    document.getElementById("v2").value = event.data.v2;
    document.getElementById("op").textContent = event.data.op;
    document.getElementById("ans").textContent = event.data.ans;
  });
});
</script>
add.htm
<title>加算</title>
<!-- 略 -->

<div id="d1"></div>
<!-- 以下略 -->

<script>
var channel = new MessageChannel();
window.parent.postMessage({},"/",[channel.port2]);    // ポートを送信
channel.port1.start();

window.addEventListener('message', function(event){
  document.getElementById('d1').textContent = event.data.a + " " + event.data.b;
  var p = event.source.document;
  var v1 = parseFloat(event.data.a);
  var v2 = parseFloat(event.data.b);
  channel.port1.postMessage({v1:v1, v2:v2, op:"+", ans:v1 + v2});    // 演算結果をポートを通して送信
});
</script>
実行例

10.4.6  UIEvent

abort、error、load、resize、scroll、select、unload イベント発生時、イベントハンドラーに引き渡されるイベントオブジェクトです。Event オブジェクトを継承しています。

(1) プロパティ

Event オブジェクトのプロパティに加え、主なプロパティとして以下のものがあります。

プロパティ
detailR/Oイベントのタイプに応じて、イベントの詳細
layerXR/Oレイヤー上における相対的な水平(X)座標
layerYR/Oレイヤー上における相対的な垂直(Y)座標
pageXR/Oウェブページの左上が基点の水平(X)座標
pageYR/Oウェブページの左上が基点の垂直(Y)座標
レイヤー上における...
ウェブページ(ドキュメント)の左上が基点で、スクロールしても変わりません。ただし static 以外の position が指定されたボックスなどであれば、基点はボックスの左上になります。

10.4.7  MouseEvent

click、contextmenu、dblclick、mousedown、mouseenter、mouseleave、mousemove、mouseout、mouseover、mouseup などのイベント発生時、イベントハンドラーに引き渡されるイベントオブジェクトです。UIEvent オブジェクトを継承しています。

(1)プロパティ

UIEvent オブジェクトのプロパティに加え、主なプロパティとして以下のものがあります。

プロパティ戻り値
altKeyR/OAlt キーが押されているかどうか(true:押されている、false:押されていない)
buttonR/O押されているボタンの番号
説明
0メインボタン(通常左ボタン)
1中央ボタン(もしくはホイールのクリック)
2第二ボタン(通常右ボタン)
3第四ボタン
4第五ボタン
buttonsR/O同時に押されているボタンの番号(複数押されていたらこれらの和))
説明
1左ボタン
2右ボタン
4中央ボタン(もしくはホイールのクリック)
8第四ボタン
16第五ボタン
clientXR/Obody や iframe 内のマウスポインタの X 座標
(body や iframe の左上が原点)
clientYR/Obody や iframe 内のマウスポインタの Y 座標
(body や iframe の左上が原点)
ctrlKeyR/OCtrl キーが押されているかどうか (true:押されている、false:押されていない)
metaKeyR/OMeta(Windows) キーが押されているかどうか (true:押されている、false:押されていない)
movementXR/O前の mousemove イベントの位置からの X 方向の移動距離 (右が正)
movementYR/O前の mousemove イベントの位置からの Y 方向の移動距離 (下が正)
offsetXR/O対象要素内のマウスポインタの X 座標
(対象要素の左上が原点)
offsetYR/O対象要素内のマウスポインタの Y 座標
(対象要素の左上が原点)
relatedTargetR/Oイベントの影響を受けた要素オブジェクト
イベントrelatedTarget
mouseenter直前にマウスポインタが乗っていた要素
mouseleave直後にマウスポインタが乗った要素
mouseout直後にマウスポインタが乗った要素
mouseover直前にマウスポインタが乗っていた要素
screenXR/O画面上のマウスポインタの X 座標
(メインディスプレイの左上が原点)
screenYR/O画面上のマウスポインタの Y 座標
(メインディスプレイの左上が原点)
shiftKeyR/OShift キーが押されているかどうか (true:押されている、false:押されていない)

記述例(クリック)
<span id="d11"></span> <span id="d12"></span> <span id="d13"></span>
<!-- 以下略 -->

<script>
function disp(event) {
  event.preventDefault();    // デフォルトの処理を行わない
  document.getElementById("d11").textContent = event.shiftKey;
  document.getElementById("d12").textContent = event.ctrlKey;
  document.getElementById("d13").textContent = event.altKey;
  document.getElementById("d21").textContent = event.button;
  document.getElementById("d22").textContent = event.buttons;
  document.getElementById("d31").textContent = "(" + event.screenX + "," + event.screenY + ")";
  document.getElementById("d32").textContent = "(" + event.clientX + "," + event.clientY + ")";
  document.getElementById("d33").textContent = "(" + event.offsetX + "," + event.offsetY + ")";
}
var p = document.getElementById("p");
p.addEventListener('mouseup', disp, false);
p.addEventListener('mousedown', disp, false);
</script>

Shift キーや Ctrl キー、Alt キーなども押しながら黄色い四角内をクリックしてみてください。押されているキーやクリックした座標が表示されます。

button、buttons は、click イベントでは正しく取得できませんので、この例では、mouseup、mousedown イベントですべての情報を得ています。

実行例

注意

button、buttons は、click イベントでは正しく取得できないようです。この例では、click イベントで情報を得ています。


記述例(移動)
<span id="d11"></span> <span id="d12"></span> <span id="d13"></span>
<span id="d21"></span>

<script>
function move(event) {
  event.preventDefault();    // デフォルトの処理を行わない
  document.getElementById("d11").textContent = "(" + event.screenX + "," + event.screenY + ")";
  document.getElementById("d12").textContent = "(" + event.clientX + "," + event.clientY + ")";
  document.getElementById("d13").textContent = "(" + event.offsetX + "," + event.offsetY + ")";
  document.getElementById("d21").textContent = "(" + event.movementX + "," + event.movementY + ")";
}
var p = document.getElementById("p");
p.addEventListener('mousemove', move, false);
</script>

黄色い四角内でマウスポインターを移動させてみてください。移動している座標が表示されます。

実行例

記述例(対象要素)

マウスポインターの移動前の要素、あるいは移動後の要素を得ることができます。

<table style="border-collapse:collapse;font-size:9pt;">
  <tr style="vertical-align:top;">
    <td id="A" class="box outer"></td>
    <td id="B" class="box inner"></td>
  </tr>
  <tr style="vertical-align:top;">
    <td id="C" class="box inner"></td>
    <td id="D" class="box outer"></td>
  </tr>
</table>

<script>
function disp(event, n, dir1, dir2) {
  if (event.relatedTarget == null)
    return;
  event.preventDefault();    // デフォルトの処理を行わない
  document.getElementById(n).innerHTML = event.target.id + "   (" + event.type + ")<br>" 
           + "relatedTarget : " + dir1 + event.relatedTarget.id + dir2;
}
var topLeft = document.getElementById("A");
topLeft.addEventListener('mouseleave', function(event) {disp(event, "A", "→", "");}, false);
topLeft.addEventListener('mouseover', function(event) {disp(event, "A", "", "→");}, false);
var topRight = document.getElementById("B");
topRight.addEventListener('mouseleave', function(event) {disp(event, "B", "→", "");}, false);
topRight.addEventListener('mouseover', function(event) {disp(event, "B", "", "→");}, false);
var bottomLeft = document.getElementById("C");
bottomLeft.addEventListener('mouseleave', function(event) {disp(event, "C", "→", "");}, false);
bottomLeft.addEventListener('mouseover', function(event) {disp(event, "C", "", "→");}, false);
var bottomRight = document.getElementById("D");
bottomRight.addEventListener('mouseleave', function(event) {disp(event, "D", "→", "");}, false);
bottomRight.addEventListener('mouseover', function(event) {disp(event, "D", "", "→");}, false);
</script>

4つの領域の中でマウスポインターを移動させてみてください。領域ごとに発生したイベントと relatedTarget(この例では relatedTarget の id)が表示されます。

"名前→" は、名前の領域から移動してきたことを表し、"→名前" は名前の領域に移動したことを表しています。

実行例

(2) インスタンス生成

MouseEvent のインスタンスを生成します。

new MouseEvent(type[,init])

MouseEvent インスタンスを生成する。

引数 type:イベント名(click、dblclick、mouseup、mousedown など)

引数 init:初期値マップ  形式({ "key":value, ... })

(なお、MouseEvent は UIEvent を継承しているため、UIEvent や Event の key も指定できる)

key意味
screenX画面上の、イベントの発生した X 座標(0~)(規定値:0)
screenY画面上の、イベントの発生した Y 座標(0~)(規定値:0)
clientXbody や iframe 内の、イベントの発生した X 座標(0~)(規定値:0)
clientYbody や iframe 内の、イベントの発生した Y 座標(0~)(規定値:0)
ctrlKeyCtrl キーが押されているかどうか(true:押されている、false:押されていない)(規定値:false)
shiftKeyShift キーが押されているかどうか(true:押されている、false:押されていない)(規定値:false)
altKeyAlt キーが押されているかどうか(true:押されている、false:押されていない)(規定値:false)
metaKeyMeta(Windows) キーが押されているかどうか(true:押されている、false:押されていない)(規定値:false)
button押されているボタンの番号
説明
0メインボタン(通常左ボタン)
1中央ボタン(もしくはホイールのクリック)
2第二ボタン(通常右ボタン)
3第四ボタン
4第五ボタン
(規定値:0)
buttons同時に押されているボタンの番号
説明
0押されていない
1メインボタン(通常左ボタン)
2第二ボタン(通常右ボタン)
4中央ボタン(もしくはホイールのクリック)
(規定値:0)
relatedTargetイベントの影響を受ける要素オブジェクト
イベントrelatedTarget
mouseenter直前にマウスポインタが乗っていた要素
mouseleave直後にマウスポインタが乗った要素
mouseout直後にマウスポインタが乗った要素
mouseover直前にマウスポインタが乗っていた要素
(規定値:null)
regionイベントによって影響を受ける要素の ID(規定値:null)

戻り値:MouseEvent インスタンス

黄色い四角を直接クリックしたときに発生するイベントと同じものを「クリック」ボタンによって生成します。

ただし、clientX などの座標は実際にクリックしていないので設定された値をそのまま送信します。したがって、screenX と clientX との間などに矛盾があるかもしれません。

記述例
<table>
<tr><td>
 <input id="shft" type="checkbox"> <input id="ctrl" type="checkbox" checked> <input id="alt" type="checkbox"> <input id="meta" type="checkbox"> 
 <input id="screenX" type="text" size="4" value="100"> <input id="screenY" type="text" size="4" value="200">
</td><td rowspan="2">
 <div class="switch" onclick="fire();">クリック</div>
</td></tr>
<tr><td>
 <input id="left" type="checkbox" checked> <input id="middle" type="checkbox"> <input id="right" type="checkbox">
</td></tr>
</table>

<div id="p" class="box" style="width:50px;height:50px;margin:10px;"></div>
<span id="d11"></span> <span id="d12"></span> <span id="d13"></span> <span id="d14"></span><br>
<!-- 以下略 -->

<script>
function fire() {
  var bLeft = document.getElementById("left").checked;
  var bMiddle = document.getElementById("middle").checked;
  var bRight = document.getElementById("right").checked;
  var init = {
      "shiftKey" : document.getElementById("shft").checked,
      "ctrlKey" : document.getElementById("ctrl").checked,
      "altKey" : document.getElementById("alt").checked,
      "metaKey" : document.getElementById("meta").checked,
      "button" : bLeft ? 0 : (bMiddle ? 1 : 2),
      "buttons" : (bLeft ? 1 : 0) | (bRight ? 2 : 0) | (bMiddle ? 4 : 0),
      "screenX" : parseInt(document.getElementById("screenX").value),
      "screenY" : parseInt(document.getElementById("screenY").value),
      "clientX" : parseInt(document.getElementById("clientX").value),
      "clientY" : parseInt(document.getElementById("clientY").value)
  }
  var evt = new MouseEvent("click", init);    // 入力された情報をもとに MouseEvent オブジェクトを生成
  p.dispatchEvent(evt);                       // イベントを送信
}

function click(event) {
  event.preventDefault();    // デフォルトの処理を行わない
  document.getElementById("d11").textContent = event.shiftKey;
  document.getElementById("d12").textContent = event.ctrlKey;
  document.getElementById("d13").textContent = event.altKey;
  document.getElementById("d14").textContent = event.metaKey;
  document.getElementById("d21").textContent = event.button;
  document.getElementById("d22").textContent = event.buttons;
  document.getElementById("d31").textContent = "(" + event.screenX + "," + event.screenY + ")";
  document.getElementById("d32").textContent = "(" + event.clientX + "," + event.clientY + ")";
}

var p = document.getElementById("p");
p.addEventListener("click", click, false);
</script>

「クリック」ボタンをクリックしてください。

実行例

10.4.8  DragEvent

drag、dragend、dragenter、dragexit、dragleave、dragover、dragstart、drop イベント発生時、イベントハンドラーに引き渡されるイベントオブジェクトです。MouseEvent オブジェクトを継承しています。

(1) プロパティ

MouseEvent オブジェクトのプロパティに加え、主なプロパティとして以下のものがあります。

プロパティ
dataTransferR/Oドラッグアンドドロップの操作で動かされているデータ(DataTransfer オブジェクト)
記述例
<div>
この文章のどこでも好きなところを選択して、下のボックスにドラッグしてください。<img src="bear.png">
</div>

<div id="box"></div>
<div id="d1"></div>
<!-- 以下略 -->

<script>
var text;
var node;
var timer;
var count = 0;
function imageLoaded() {
  if (node.naturalHeight > 0) {   // ie 以外は読み込めてなくても node.complete が true になる
    window.clearInterval(timer);
    set();
  }
  else {
    if (--count < 0) {
      window.clearInterval(timer);
      delete node;       // 画像が読み込めなければ通常のテキスト表示にする
      node = document.createTextNode(text);
      set();
    }
  }
}
function  createNode(text) {
  node = new Image();
  node.src = text;         // text を画像の URL として img 要素を作る
  count = 12;
  timer = setInterval('imageLoaded()', 1000 / count);
}
function dispFiles(files) {
  var f = "";
  for (var i = 0 ; i < files.length ; i++) {
    f += files[i].name + " ";
  }
  return f;
}
function dispTypes(types) {
  var t = "";
  for (var i = 0 ; i < types.length ; i++) {
    t += types[i] + " ";
  }
  return t;
}
function cancel(event) {
  event.preventDefault();
}
function dragstart(event) {    // 他のウィンドウからドラッグが始まった時はここは実行されない
  if (event.target.src != undefined)    // src 属性があれば img 要素
    event.dataTransfer.setData("Text", event.target.src);
  else
    event.dataTransfer.setData("Text", window.getSelection().toString());
}
var dropEffect;
var effectAllowed;
var files;
var types;
function drop(event) {
  event.preventDefault();
  try {
    dropEffect = event.dataTransfer.dropEffect;
    effectAllowed = event.dataTransfer.effectAllowed;
  }
  catch(e) {
    effectAllowed = "";
  }
  files = event.dataTransfer.files;
  types = event.dataTransfer.types;
  text = event.dataTransfer.getData("Text");    // 他のウィンドウからドラッグが始まった時は値が設定されていない
  var f = dispFiles(files);
  var t = dispTypes(types);
  if (text == "")
    text = f;
  createNode(text);
}
function set() {
  document.getElementById("box").appendChild(node);
  document.getElementById("d1").textContent = dropEffect;
  document.getElementById("d2").textContent = effectAllowed;
  document.getElementById("d3").textContent = dispFiles(files);
  document.getElementById("d4").textContent = dispTypes(types);
}
document.getElementById("box").addEventListener('drop', drop, false);
document.getElementById("box").addEventListener('dragover'", cancel, false);

window.addEventListener('dragstart', dragstart, false);
</script>

選択した文字列か画像をドラッグして、下のボックスに移してください。

ドロップしたときの dataTransfer の主な内容を表示しています。ただし、この内容はブラウザによって異なります。

また、エクスプローラーからファイルをドロップすると files にファイル情報が設定されます。

なお、ボックスをダブルクリックすると初期状態に戻ります。

実行例

10.4.9  WheelEvent

mousewheel イベント発生時、イベントハンドラーに引き渡されるイベントオブジェクトです。MouseEvent オブジェクトを継承しています。

(1) プロパティ

WheelEvent 固有のプロパティは次のようなものがあります。

プロパティ
deltaXR/O水平方向のスクロール量(横方向の回転量)左が負×
deltaYR/O垂直方向のスクロール量(縦方向の回転量)上が負
deltaZR/OZ 軸方向のスクロール量(通常 0)
deltaModeR/Oスクロール量の差分値の単位
定数説明
DOM_DELTA_PIXEL0ピクセル数
DOM_DELTA_LINE1行数
DOM_DELTA_PAGE2ページ数
×

また、いくつかのブラウザでは MouseWheelEvent(?) のイベントオブジェクトが引数として渡るようです。ただし、回転方向と数値の正負が WheelEvent とは逆になっています。

プロパティ
wheelDeltaR/O垂直方向のスクロール量(縦方向の回転量)上が正×
wheelDeltaXR/O水平方向のスクロール量(横方向の回転量)左が正×
wheelDeltaYR/O垂直方向のスクロール量(縦方向の回転量)上が正
記述例
<div id="p">    <!-- 黄色の四角 -->
X → <span id="x"></span><br>
Y → <span id="y"></span><br>
</div>

<script>
function limit(s, v, d, l, h) {
  s += v / d;
  if (s < l)
    s = l;
  else if (s > h)
    s = h;
  return s;
}
var w = 100;
var h = 75;
function resize(event) {
  event.preventDefault();    // デフォルトの処理を行わない
  var x = 0;
  var y = 0;
  var d = 0;
  if (event.deltaX == undefined) {
    if (event.wheelDeltaX == undefined) {
      x = 0;
      y = event.wheelDelta;   // IE
    }
    else {
      x = event.wheelDeltaX;  // Safari
      y = event.wheelDeltaY;
    }
    d = 120;
  }
  else {
    x = event.deltaX;         // Edge Chrome Opera Sleipnir
    y = event.deltaY;
    d = 100;
  }
  document.getElementById("x").textContent = x;
  document.getElementById("y").textContent = y;
  w = limit(w, x, d, 50, 500);
  h = limit(h, y, d, 50, 100);
  p.style.width = w + "px";
  p.style.height = h + "px";
}
var p = document.getElementById("p");
p.addEventListener('mousewheel', resize, false);
</script>

黄色い四角の上でマウスホイールを回転させてください。回転量が表示され黄色い矩形のサイズが変わります。横方向に対応したマウスでは水平方向も変わります。

実行例

10.4.10  FocusEvent

focus、blur イベント発生時、イベントハンドラーに引き渡されるイベントオブジェクトです。UIEvent オブジェクトを継承しています。


(1) プロパティ

FocusEvent 固有のプロパティは次のようなものがあります。

プロパティ
relatedTargetR/Oイベントの影響を受けた要素オブジェクト
イベントrelatedTarget
focus直前にフォーカスを持っていた要素
blur直後にフォーカスを持った要素

ただし、セキュリティ上の理由から null が返るブラウザもある。
記述例
<form id="f" name="f">
  <textarea id="A" name="A" rows="3" cols="20"></textarea> <textarea id="B" name="B" rows="3" cols="20"></textarea><br>
  <textarea id="C" name="C" rows="3" cols="20"></textarea> <textarea id="D" name="D" rows="3" cols="20"></textarea><br>
</form>
<script>
function disp(event, n, dir1, dir2) {
  if (event.relatedTarget == null)
    return;
  event.preventDefault();    // デフォルトの処理を行わない
  document.f.elements[n].value = event.target.id + "   (" + event.type + ")\n" 
           + "relatedTarget : " + dir1 + event.relatedTarget.id + dir2 + "\n";
}

var topLeft = document.getElementById("A");
topLeft.addEventListener('focus', function(event) {disp(event, "A", "", "→");}, false);
topLeft.addEventListener('blur', function(event) {disp(event, "A", "→", "");}, false);
var topRight = document.getElementById("B");
topRight.addEventListener('focus', function(event) {disp(event, "B", "", "→");}, false);
topRight.addEventListener('blur', function(event) {disp(event, "B", "→", "");}, false);
var bottomLeft = document.getElementById("C");
bottomLeft.addEventListener('focus', function(event) {disp(event, "C", "", "→");}, false);
bottomLeft.addEventListener('blur', function(event) {disp(event, "C", "→", "");}, false);
var bottomRight = document.getElementById("D");
bottomRight.addEventListener('focus', function(event) {disp(event, "D", "", "→");}, false);
bottomRight.addEventListener('blur', function(event) {disp(event, "D", "→", "");}, false);
</script>

4つの領域を適当にクリックしてみてください。領域ごとに発生したイベントと relatedTarget(この例では relatedTarget の id)が表示されます。

"名前→" は、直前に名前の領域がフォーカスを持っていたことを表し、"→名前" は直後に名前の領域がフォーカスを持ったことを表しています。

実行例

10.4.11  KeyboardEvent

keydown、keypress、keyup イベント発生時、イベントハンドラーに引き渡されるイベントオブジェクトです。UIEvent オブジェクトを継承しています。

(1) プロパティ

KeyboardEvent 固有のプロパティは次のようなものがあります。

プロパティ
altKeyR/OAlt キーが押されているかどうか(true:押されている、false:押されていない)
codeR/Oキーのコード値を表す文字列(文字コードではないので、Shift を押していても押していなくても同じ文字列)  code 一覧
ctrlKeyR/OCtrl キーが押されているかどうか(true:押されている、false:押されていない)
keyR/O表示可能ならばその文字、そうでないならキーのコード値を表す文字列(基本的に code と同じ文字列)
localeR/Oキーボードに設定されているロケール  日本語キーボードのときは、ja-JP××××××
locationR/Oキーボードや他の入力デバイス上におけるキーの位置
意味
0キーボード上で一つしかないキー
1キーボード上の左側のキー
2キーボード上の右側のキー
3テンキー側のキー、あるいは [NumLock]が押下された状態でのキー
metaKeyR/OMeta(Windows) キーが押されているかどうか(true:押されている、false:押されていない)
repeatR/O押下し続けられているかどうか(true:押されている、false:押されていない)
shiftKeyR/OShift キーが押されているかどうか(true:押されている、false:押されていない)
記述例
<input id="t" size="1">
<span id="d11"></span><span id="d12"></span><span id="d13"></span><span id="d14"></span><br>
  <!-- 以下略 -->

<script>
function keydown(event) {
  event.preventDefault();    // デフォルトの処理を行わない
  document.getElementById("d11").textContent = event.shiftKey;
  document.getElementById("d12").textContent = event.ctrlKey;
  document.getElementById("d13").textContent = event.altKey;
  document.getElementById("d14").textContent = event.metaKey;
  document.getElementById("d21").textContent = event.key;
  document.getElementById("d22").textContent = event.code;
  document.getElementById("d23").textContent = event.location;
  document.getElementById("d41").textContent = event.repeat;
  document.getElementById("d51").textContent = event.locale;
}
var t = document.getElementById("t");
t.addEventListener('keydown', keydown, false);
</script>

どのキーでも押してみてください。押されたキーによって表示が変わります。

また、同じキーを押し続けると repeat が true になります。

実行例

10.4.12  PageTransitionEvent

pageshow、pagehide イベント発生時、イベントハンドラーに引き渡されるイベントオブジェクトです。Event オブジェクトを継承しています。

(1) プロパティ

PageTransitionEvent 固有のプロパティは次のようなものがあります。

プロパティ
persistedR/Oページがキャッシュからロードされたかどうか(true:キャッシュから、false:サーバーから)××××××
記述例
<div id="d">
<div class="switch" onclick="location.reload();">リロード</div>

<script>
window.addEventListener('pageshow', function(event) {document.getElementById("d").textContent=event.persisted;}, false);
</script>

リロードしても false しか返らないようです。

実行例

10.4.13  TouchEvent

touchcancel、touchend、touchmove、touchstart イベント発生時、イベントハンドラーに引き渡されるイベントオブジェクトです。UIEvent オブジェクトを継承しています。

(1) プロパティ

TouchEvent 固有のプロパティは次のようなものがあります。

プロパティ
altKeyR/OAlt キーが押されているかどうか(true:押されている、false:押されていない)
changedTouchesR/O前回のタッチイベントと今回のイベントの間に接触状態が変化した、個々の位置を表す Touch オブジェクトのリスト
ctrlKeyR/OCtrl キーが押されているかどうか(true:押されている、false:押されていない)
metaKeyR/OMeta(Windows) キーが押されているかどうか(true:押されている、false:押されていない)
shiftKeyR/OShift キーが押されているかどうか(true:押されている、false:押されていない)
targetTouchesR/O現在タッチ面に接触している、かつイベントのターゲットと同じ要素でタッチを始めた Touch オブジェクトのリスト
touchesR/Oターゲットや変化の状態にかかわらず、タッチ面に現在接触しているすべての個所を表す Touch オブジェクトのリスト

記述例
<div id="e" style="width:200px;height:100px;border:solid 1px gray;"></div>
<span id="d11"></span><span id="d12"></span><span id="d13"></span><span id="d14"></span><br>
<span id="d21"></span><br>
<!-- 以下略 -->

<script>
function clear() {
  document.getElementById("d11").textContent = "";
  <!-- 以下略 -->
}
function dispList(list) {
  var s = "";
  for (var i = 0 ; i < list.length ; i++) {
    s += "(" + parseInt(list[i].clientX) + "," + parseInt(list[i].clientY) + ") ";
  }
  return s;
}
function touchmove(event) {
  event.preventDefault();    // デフォルトの処理を行わない
  document.getElementById("d11").textContent = event.shiftKey;
  document.getElementById("d12").textContent = event.ctrlKey;
  document.getElementById("d13").textContent = event.altKey;
  document.getElementById("d14").textContent = event.metaKey;
  document.getElementById("d21").textContent = dispList(event.changedTouches);
  document.getElementById("d31").textContent = dispList(event.targetTouches);
  document.getElementById("d41").textContent = dispList(event.touches);
}
var e = document.getElementById("e");
e.addEventListener('touchmove',  touchmove, false);
</script>

四角の中をタッチしてみてください。(ただし、もちろんタッチパネルで)

マルチタッチにも対応しています。

実行例

10.4.14  ProgressEvent

XMLHttpRequest、または img、audio、video、style、link 要素のようなリソースを読み込むなどのプロセスの進捗の進み具合を表すイベントオブジェクトです。Event オブジェクトを継承しています。

(1) プロパティ

TouchEvent 固有のプロパティは次のようなものがあります。

プロパティ
lengthComputable R/O進行状況が測定可能(true)かそうでない(false)かを示す
loadedR/Oすでに実行されている作業量
totalR/O進行中の作業の総量

サーバーによっては、lengthComputable は false、total は 0 のままのことがある。


記述例
<span id="d21"></span><br>

<script>
var loaded = document.getElementById("d1");
var total = document.getElementById("d2");
var percentage = document.getElementById("d3");
var client = new XMLHttpRequest();
client.open("GET", "large.png");
client.onprogress = function(pe) {
  if (pe.lengthComputable) {
    loaded.textContent = pe.loaded;
    if (pe.total > 0) {
      total.textContent = pe.total;
      percentage.textContent = (pe.loaded * 100 / pe.total).toFixed(1) + "%"; 
    }
  }
}
client.onloadend = function(pe) {
  loaded.textContent = pe.loaded;
  total.textContent = pe.total;
  if (pe.total > 0) {
    percentage.textContent = (pe.loaded * 100 / pe.total).toFixed(1) + "%";
  }
}
client.send()
</script>
実行例
再実行