Skip to content

Web/API/EventTarget/addEventListener を更新 #27398

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 12 additions & 66 deletions files/ja/web/api/eventtarget/addeventlistener/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: "EventTarget: addEventListener() メソッド"
short-title: addEventListener()
slug: Web/API/EventTarget/addEventListener
l10n:
sourceCommit: ded971d7fec855c2b81fde8809172697f2e227c1
sourceCommit: be1922d62a0d31e4e3441db0e943aed8df736481
---

{{APIRef("DOM")}}{{AvailableInWorkers}}
Expand Down Expand Up @@ -55,12 +55,12 @@ addEventListener(type, listener, useCapture)
- : 論理値で、 `listener` の呼び出しを一回のみのとしたいかどうかを値で指定します。 `true` を指定すると、 `listener` は一度実行された時に自動的に削除されます。指定されていない場合は、既定で `false` になります。
- `passive` {{optional_inline}}

- : 論理値で、`true` ならば、 `listener` で指定された関数が {{domxref("Event.preventDefault", "preventDefault()")}} を呼び出さないことを示します。呼び出されたリスナーが `preventDefault()` を呼び出すと、ユーザーエージェントは何もせず、コンソールに警告を出力します
- : 論理値で、`true` ならば、 `listener` で指定された関数が {{domxref("Event.preventDefault", "preventDefault()")}} を呼び出さないことを示します。呼び出されたリスナーが `preventDefault()` を呼び出すと、ユーザーエージェントは何もせず、コンソールに警告を出力される可能性があります

このオプションが指定されていない場合、既定で `false` になります。ただし、Safari 以外のブラウザーでは、{{domxref("Element/wheel_event", "wheel")}}、{{domxref("Element/mousewheel_event", "mousewheel")}}、{{domxref("Element/touchstart_event", "touchstart")}}、{{domxref("Element/touchmove_event", "touchmove")}} の各イベントでは `true` になります。詳細は[パッシブリスナーの使用](#パッシブリスナーの使用)をご覧ください。

- `signal` {{optional_inline}}
- : {{domxref("AbortSignal")}} です。指定された `AbortSignal` オブジェクトの {{domxref("AbortController/abort()", "abort()")}} メソッドが呼び出された時に、リスナーが削除されます。指定されていない場合は、`AbortSignal` がリスナーに関連付けられません。
- : {{domxref("AbortSignal")}} です。その `AbortSignal` を持つ {{domxref("AbortController")}} オブジェクトの {{domxref("AbortController/abort()", "abort()")}} メソッドが呼び出された時に、リスナーが削除されます。指定されてなかった場合は、`AbortSignal` がリスナーに関連付けられません。

- `useCapture` {{optional_inline}}

Expand All @@ -69,7 +69,7 @@ addEventListener(type, listener, useCapture)

> [!NOTE]
> イベントターゲットに登録されたイベントリスナーは、キャプチャフェーズやバブリングフェーズではなく、ターゲットフェーズのイベントになります。
> キャプチャフェーズのイベントリスナーは、キャプチャフェーズ以外のイベントリスナーよりも先に呼び出されます
> キャプチャフェーズのイベントリスナーは、ターゲットフェーズおよびバブリングフェーズのイベントリスナーの前に呼び出されます

- `wantsUntrusted` {{optional_inline}} {{non-standard_inline}}
- : Firefox (Gecko) 独自の引数です。`true` の場合、このリスナーはウェブコンテンツによって発行された合成イベント (カスタムイベント) を受け取ります (ブラウザーの{{glossary("chrome", "クローム")}}では既定で `false` ですが、一般のウェブページでは `true` です)。この引数は、主にアドオンやブラウザー自身の役に立つものです。
Expand Down Expand Up @@ -98,52 +98,6 @@ function handleEvent(event) {
}
```

### オプションの対応の安全な検出

DOM 仕様書の古い版では、 `addEventListener()` の第 3 引数はキャプチャーを使用するかどうかを示す論理値でした。時間の経過とともに、より多くのオプションが必要であることが明らかになりました。関数にさらに多くの引数を追加する (オプションの値を扱うときに非常に複雑になります) のではなく、第 3 引数は、イベントリスナーを削除する過程を設定するためのオプションの値を定義するさまざまなプロパティを含むことができるオブジェクトに変更されました。

古いブラウザーは (あまり古くないブラウザーも含めて) 第 3 引数がまだ論理値であると仮定しているので、このシナリオをインテリジェントに処理できるようにコードを構築する必要があります。これを行うには、興味のあるオプションごとに機能検出を使用します。

例えば、 `passive` オプションをチェックしたい場合は次のようにします。

```js
let passiveSupported = false;

try {
const options = {
get passive() {
// この関数はブラウザーが passive プロパティに
// アクセスしようとしたときに呼び出されます。
passiveSupported = true;
return false;
},
};

window.addEventListener("test", null, options);
window.removeEventListener("test", null, options);
} catch (err) {
passiveSupported = false;
}
```

これは、 `options` オブジェクトを生成し、 `passive` プロパティのゲッター関数を持たせます。ゲッターは、呼ばれた場合に `passiveSupported` フラグを `true` に設定します。つまり、ブラウザーが `passive` プロパティの値を `options` オブジェクトでチェックした場合、 `passiveSupported` は `true` に設定され、そうでなければ `false` のままになります。次に `addEventListener()` を呼び出して、これらのオプションを指定して偽のイベントハンドラーをセットアップし、ブラウザーが第 3 引数としてオブジェクトを認識した場合にオプションがチェックされるようにします。その後、[`removeEventListener()`](/ja/docs/Web/API/EventTarget/removeEventListener) を呼び出して、自分たちで後始末をします。(呼ばれていないイベントリスナーでは `handleEvent()` は無視されることに注意してください。)

この方法で、任意のオプションに対応しているかどうかを確認することができます。上に示したようなコードを使って、そのオプションのゲッターを追加するだけです。

そして、問題のオプションを使用する実際のイベントリスナーを作成したい場合は、次のようにします。

```js
someElement.addEventListener(
"mouseup",
handleMouseUp,
passiveSupported ? { passive: true } : false,
);
```

ここでは、 {{domxref("Element/mouseup_event", "mouseup")}} イベントのリスナーを `someElement` 要素に追加しています。第 3 引数の `passiveSupported` が `true` である場合、 `options` オブジェクトを `passive` を `true` に設定して指定しています。そうでない場合は、論理値を渡す必要があることがわかっているので、 `useCapture` 引数の値として `false` を渡しています。

[機能検出の実装](/ja/docs/Learn_web_development/Extensions/Testing/Feature_detection)のドキュメントや [Web Incubator Community Group](https://wicg.github.io/admin/charter.html) の [`EventListenerOptions`](https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md#feature-detection) に関する説明で詳しく学ぶことができます。

### ハンドラー内での "this" の値

イベントハンドラーが発行された要素を参照することはよくあることで、似たような要素の設定に汎用ハンドラーを使用する場合などに便利です。
Expand Down Expand Up @@ -302,8 +256,8 @@ console.log(someString); // 期待される値: 'Data' ('Data Again' とはな
const elts = document.getElementsByTagName("*");

// ケース 1
for (const elt of elts) {
elt.addEventListener(
for (const elem of elems) {
elem.addEventListener(
"click",
(e) => {
// 何かを行う
Expand All @@ -317,8 +271,8 @@ function processEvent(e) {
// 何かを行う
}

for (const elt of elts) {
elt.addEventListener("click", processEvent, false);
for (const elem of elems) {
elem.addEventListener("click", processEvent, false);
}
```

Expand All @@ -330,7 +284,7 @@ for (const elt of elts) {

イベントに既定のアクションがある場合、例えば、既定でコンテナーをスクロールする {{domxref("Element/wheel_event", "wheel")}} イベントの場合、イベントリスナーが {{domxref("Event.preventDefault()")}} を呼び出して既定のアクションをキャンセルするかどうかを事前に知ることができないため、ブラウザーは一般的にイベントリスナーが完了するまで既定のアクションを開始することができません。イベントリスナーの実行に時間がかかりすぎると、既定のアクションが実行されるまでに、{{glossary("jank", "ジャンク")}}と呼ばれる顕著な遅延が発生する可能性があります。

`passive` オプションを `true` に設定することで、イベントリスナーは既定のアクションを取り消される可能性がないことを宣言します。リスナーが {{domxref("Event.preventDefault()")}} を呼び出しても、効果はありません。
`passive` オプションを `true` に設定すると、イベントリスナーは既定のアクションを取り消さないことを宣言するため、ブラウザーはリスナーが完了するのを待たずに、既定のアクションをすぐに開始できます。リスナーが {{domxref("Event.preventDefault()")}} を呼び出しても、効果はありません。

`addEventListener()` の仕様書では、`passive` オプションの既定値は常に `false` であると定義しています。しかし、パッシブリスナーのスクロールパフォーマンスの利点を古いコードで実現するために、最近のブラウザーでは {{domxref("Element/wheel_event", "wheel")}}、{{domxref("Element/mousewheel_event", "mousewheel")}}、{{domxref("Element/touchstart_event", "touchstart")}}、{{domxref("Element/touchmove_event", "touchmove")}} の各イベントの `passive` オプションの既定値が、文書レベルノード {{domxref("Window")}}、{{domxref("Document")}}、{{domxref("Document.body")}} においては `true` に変更されています。これにより、イベントリスナーが[イベントが取り消される可能性](/ja/docs/Web/API/Event/preventDefault)を防ぐことができるので、ユーザーがスクロールしている間にページのレンダリングをブロックすることはありません。

Expand All @@ -341,10 +295,6 @@ for (const elt of elts) {

パッシブリスナーの効果を示す例については[パッシブリスナーによるスクロールの性能改善](#パッシブリスナーによるスクロールの性能改善)を参照してください。

### 古いブラウザーの場合

`addEventListener()` の引数 `options` に対応していない古いブラウザーでは、これを使用しようとすると、[機能検出](#オプションの対応の安全な検出)を適切に使用しない限り、引数 `useCapture` が使用できなくなります。

## 例

### シンプルなリスナーの追加
Expand Down Expand Up @@ -473,7 +423,7 @@ el.addEventListener(

### アロー関数を使用したイベントリスナー

この例はアロー関数記法を使用して実装された、簡単なイベントリスナーを紹介しています
この例はアロー関数記法を使用して実装されたイベントリスナーを紹介しています

#### HTML

Expand Down Expand Up @@ -656,8 +606,6 @@ function nonePassiveHandler(event) {

{{ EmbedLiveSample('options_の使い方の例', 600, 630) }}

`options` オブジェクトで特定の値を使用する前に、ユーザーのブラウザーがその値に対応していることを確認するのが良いでしょう。これらは歴史的にすべてのブラウザーがサポートしてきたわけではない追加要素であるからです。詳細は[オプションの対応の安全な検出](#オプションの対応の安全な検出)を参照してください。

### 複数のオプションを持つイベントリスナー

引数の `options` には複数のオプションを設定することができます。次の例では、2 つのオプションを設定しています。
Expand All @@ -667,11 +615,9 @@ function nonePassiveHandler(event) {

#### HTML

```html
```html-nolint
<button id="example-button">このボタンはクリックされていません。</button>
<button id="reset-button">
このボタンをクリックすると、最初のボタンがリセットされます。
</button>
<button id="reset-button">このボタンをクリックすると、最初のボタンがリセットされます。</button>
```

#### JavaScript
Expand Down