ウェブプラットフォームでは、DOM イベントを通知するための方法をいくつか提供しています。よく使われる2つの方法は、一般化された addEventListener()
と、具体的な on-イベントハンドラ一式です。このページでは、後者がどのように機能するのかの詳細について注目します。
on-イベントハンドラの登録
on-イベントハンドラは、その要素がどのようにイベントに反応するかを管理しやすくするための DOM 要素に提供された一覧のプロパティです。対話型要素 (リンク、ボタン、画像、フォームなど) にも非対話型要素 (ベース文書など) にもあります。イベントは、クリック、押されたキーの検出、フォーカスの取得などの行為です。 on-イベントハンドラは通常、onclick
、onkeypress
、onfocus
など、反応するように設計されたイベントに従って名前が付けられます。
定められたオブジェクトの特定のイベント (click
など) に対して on<...>
イベントハンドラをさまざまな方法で指定することができます。
- 要素に
on{eventtype}
という名前の HTML 属性を使用します。例:
<button onclick="return handleClick(event);">
, - または、JavaScript から対応するpropertyを設定します。例:
document.getElementById("mybutton").onclick = function(event) { ... }
.
各オブジェクトは、与えられたイベントに対して 1 つの on-イベントハンドラしか持てないことに注意してください (ただし、そのハンドラは複数のサブハンドラを呼び出すことができます)。同じイベントおよび/または同じ要素に対しですら、さまざまなイベントハンドラを互いに独立して適用したい場合はとくに、addEventListener()
がイベントの通知を受け取るためのより良い方法であることが多いのはこのためです。
また、 on-イベントハンドラは、実際のハンドラ関数を割り当てることができるプレースホルダーとして機能するため、プログラマーの意思ではなく自動的に呼び出されることにも注意してください (ただし、 mybutton.onclick(myevent);
のように使用することはできます)。
非要素オブジェクト
イベントハンドラはまた、 window
, document
, XMLHttpRequest
などを含む、イベントを生成する多くの非要素オブジェクトのプロパティを使用して設定することもできます。次に例を示します。
xhr.onprogress = function() { ... }
詳細
on<...> 属性に対する HTML の値と対応する JavaScript プロパティ
on<...>
属性を介して登録されたハンドラは、対応する on<...>
プロパティを介して利用できますが、その逆はできません:
<div id="a" onclick="alert('old')">Open the Developer Tools Console to see the output.</div> <script> window.onload = function () { var div = document.getElementById("a"); console.log("Attribute reflected as a property: ", div.onclick.toString()); // Prints: function onclick(event) { alert('old') } div.onclick = function() { alert('new') }; console.log("Changed property to: ", div.onclick.toString()); // Prints: function () { alert('new') } console.log("Attribute value is unchanged: ", div.getAttribute("onclick")); // Prints: alert('old') } </script>
歴史的な理由から、<body>
および <frameset>
要素の一部の属性/プロパティは、実際にはその親 Window
オブジェクトにイベントハンドラを設定します。(HTML 仕様はこれらを onblur
, onerror
, onfocus
, onload
, onscroll
と命名しています。)
イベントハンドラのパラメータ、this
バインディング、および返値
イベントハンドラが HTML 属性として指定されている場合、指定されたコードは次のパラメーターを持つ関数にラップされます:
event
- {domxref("GlobalEventHandlers.onerror", "onerror")}} を除くすべてのイベントハンドラ。onerror
イベントハンドラのevent
,source
,lineno
,colno
およびerror
。event
パラメーターには、実際にはエラーメッセージが文字列として含まれています。
イベントハンドラが呼び出されると、ハンドラ内の this
キーワードは、ハンドラが登録されている DOM 要素に設定されます。詳しくは、this キーワードの資料を参照してください。
ハンドラからの戻り値は、イベントが取り消されるかどうかを決定します。戻り値の具体的な処理はイベントの種類によって異なります。詳細については、HTML 仕様の「イベントハンドラ処理アルゴリズム」を参照してください。
イベントハンドラが呼び出されたとき
作成中 (非捕獲リスナー)
用語集
イベントハンドラという用語は、次のように使用されます。
- イベントの通知を受けるように登録されている関数またはオブジェクト
- または、より具体的には、
<button onclick="alert(this)">
やwindow.onload = function() { /* ... */ }
など、HTML のon...
属性または Web API のプロパティを介してイベントリスナーを登録するメカニズム。
イベントをリッスンするためのさまざまな方法を議論するときは、
- イベントリスナーは、
EventTarget.addEventListener()
によって登録された関数またはオブジェクトを参照します。 - 一方、イベントハンドラは
on...
属性またはプロパティを介して登録された関数を指します。
仕様書
仕様書 | 状態 | 備考 |
---|---|---|
HTML Living Standard event handlers の定義 |
現行の標準 | |
HTML5 event handlers の定義 |
勧告 |
ブラウザーの互換性
Firefox 9 におけるイベントハンドラの変更
In order to better match the specifications, and improve cross-browser compatibility, the way event handlers were implemented at a fundamental level changed in Gecko 9.0 (Firefox 9.0 / Thunderbird 9.0 / SeaMonkey 2.6).
Specifically, in the past, event handlers were not correctly implemented as standard IDL attributes. In Gecko 9.0, this was changed. Because of this, certain behaviors of event handlers in Gecko have changed. In particular, they now behave in all the ways standard IDL attributes behave. In most cases, this shouldn't affect web or add-on content at all; however, there are a few specific things to watch out for.
イベントハンドラプロパティが存在することの検出
You can now detect the presence of an event handler property (that is, for example, onload
), using the JavaScript in
operator. For example:
if ("onsomenewfeature" in window) { /* do something amazing */ }
イベントハンドラとプロトタイプ
You can't set or access the values of any IDL-defined attributes on DOM prototype objects; that means you can't, for example, change Window.prototype.onload
anymore. In the past, event handlers (onload
, etc.) weren't implemented as IDL attributes in Gecko, so you were able to do this for those. Now you can't. This improves compatibility.