IDBCursor.source - Web API

IDBCursor.source
================

`IDBCursor` インターフェイスの読み取り専用プロパティ **`source`** は、カーソルが反復している対象の `IDBObjectStore` または `IDBIndex` を返します。この関数は、カーソルが反復中であっても、最後まで反復した後であっても、トランザクションが実行中でなくても、`null` を返したり例外を投げたりすることはありません。

**注:** この機能は Web Worker 内で利用可能です

値
-

カーソルが反復している対象の `IDBObjectStore` または `IDBIndex` です。

例
-

このシンプルな断片では、トランザクションを作成し、オブジェクトストアを取得し、カーソルを使用してオブジェクトストア内の全レコードを走査します。それぞれの繰り返しにおいて、カーソルの反復元を記録します。これにより、たとえば以下のような `IDBobjectStore` オブジェクトがコンソールに記録されます。

```json
IDBObjectStore {autoIncrement: false, transaction: IDBTransaction, indexNames: DOMStringList, keyPath: "albumTitle", name: "rushAlbumList"…}
```

カーソルを使う場合、データをキーで選択する必要はなく、単に全部取得できます。また、ループ中のそれぞれの繰り返しにおいて、カーソルオブジェクトが指している現在のレコードからデータを `cursor.value.foo` のようにして取得できます。動く例全体は、IDBCursor example を参照してください。(動く例を見る)

```js
function displayData() {
  const transaction = db.transaction(["rushAlbumList"], "readonly");
  const objectStore = transaction.objectStore("rushAlbumList");

  objectStore.openCursor().onsuccess = (event) => {
    const cursor = event.target.result;
    if (cursor) {
      const listItem = document.createElement("li");
      listItem.textContent = `${cursor.value.albumTitle}, ${cursor.value.year}`;
      list.appendChild(listItem);

      console.log(cursor.source);
      cursor.continue();
    } else {
      console.log("全エントリーを表示しました。");
    }
  };
}
```

仕様書
---

| Specification |
| --- |
| Indexed Database API 3.0 # ref-for-dom-idbcursor-source① |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

関連情報
----

* IndexedDB の使用
* トランザクションの開始: `IDBDatabase`
* トランザクションの使用: `IDBTransaction`
* キーの範囲の設定: `IDBKeyRange`
* データの取得と変更: `IDBObjectStore`
* カーソルの使用: `IDBCursor`
* リファレンス例: To-do Notifications (動く例を見る)


IDBCursor.continuePrimaryKey() - Web API

IDBCursor.continuePrimaryKey()
==============================

`IDBCursor` インターフェイスの **`continuePrimaryKey()`** メソッドは、カーソルを、キーが引数として指定するキーと一致し、かつ主キーが引数として指定する主キーと一致するアイテムに進めます。

典型的な使用例は、キーを 1 個ずつ比較することなく、前に使用したカーソルが閉じた場所から反復を再開することです。

新しいカーソルのデータを読み込む前にこのメソッドを複数回呼び出す (たとえば、同じ `onsuccess` ハンドラーで `continuePrimaryKey()` を 2 回呼び出す) と、カーソルの値を得たフラグがクリアされているため、2 回目の呼び出しで `InvalidStateError` 例外が投げられます。

このメソッドは、インデックスを対象とするカーソルでのみ有効です。オブジェクトストアを対象とするカーソルで使うと、エラーが投げられます。

**注:** この機能は Web Worker 内で利用可能です

構文
--

```js
continuePrimaryKey(key, primaryKey)
```

### 引数

`key`

カーソルの位置を設定したいキーです。

`primaryKey`

カーソルの位置を設定したい主キーです。

### 返値

なし (`undefined`)

### 例外

このメソッドは、以下の種類の `DOMException` を発生させる可能性があります。

`TransactionInactiveError` `DOMException`

この `IDBCursor` のトランザクションが活性状態でないとき投げられます。

`DataError` `DOMException`

引数のキーが以下の条件のいずれかを満たすとき投げられます。

* キーが有効でない
* キーがカーソルの位置以下であり、かつカーソルの方向が `next` または `nextunique` である
* キーがカーソルの位置以上であり、かつカーソルの方向が `prev` または `prevunique` である

`InvalidStateError` `DOMException`

カーソルが現在反復中であるか、最後まで反復済みであるとき投げられます。

`InvalidAccessError` `DOMException`

カーソルの方向が `prev` でも `next` でもないとき投げられます。

例
-

以下のようにすると、前回の訪問から `"javascript"` のタグがついた全記事に対する反復を再開できます。

```js
let request = articleStore.index("tag").openCursor();
let count = 0;
let unreadList = [];
request.onsuccess = (event) => {
  let cursor = event.target.result;
  if (!cursor) {
    return;
  }
  let lastPrimaryKey = getLastIteratedArticleId();
  if (lastPrimaryKey > cursor.primaryKey) {
    cursor.continuePrimaryKey("javascript", lastPrimaryKey);
    return;
  }
  // lastIteratedArticleId を更新する
  setLastIteratedArticleId(cursor.primaryKey);
  // unreadList に 5 本の記事を追加しておく
  unreadList.push(cursor.value);
  if (++count < 5) {
    cursor.continue();
  }
};
```

仕様書
---

| Specification |
| --- |
| Indexed Database API 3.0 # ref-for-dom-idbcursor-continueprimarykey① |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

関連情報
----

* IndexedDB の使用
* トランザクションの開始: `IDBDatabase`
* トランザクションの使用: `IDBTransaction`
* キーの範囲の設定: `IDBKeyRange`
* データの取得と変更: `IDBObjectStore`
* カーソルの使用: `IDBCursor`
* リファレンス例: To-do Notifications (動く例を見る)


IDBCursor.request - Web API

IDBCursor.request
=================

`IDBCursor` インターフェイスの読み取り専用プロパティ **`request`** は、カーソルを取得するために使用された `IDBRequest` を返します。

**注:** この機能は Web Worker 内で利用可能です

値
-

`IDBRequest` のオブジェクトインスタンスです。

例
-

カーソルを開くと、そのカーソルがどの要求オブジェクトに由来するかを表す `request` プロパティがそのカーソルオブジェクトで使用可能になります。以下が例です。

```js
function displayData() {
  list.textContent = "";
  const transaction = db.transaction(["rushAlbumList"], "readonly");
  const objectStore = transaction.objectStore("rushAlbumList");

  const request = objectStore.openCursor();

  request.onsuccess = (event) => {
    const cursor = event.target.result;
    if (cursor) {
      const listItem = document.createElement("li");
      listItem.textContent = `${cursor.value.albumTitle}, ${cursor.value.year}`;
      list.appendChild(listItem);
      console.log(cursor.request);
      cursor.continue();
    } else {
      console.log("全エントリーを表示しました。");
    }
  };
}
```

仕様書
---

| Specification |
| --- |
| Indexed Database API 3.0 # ref-for-dom-idbcursor-request① |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

関連情報
----

* IndexedDB の使用
* トランザクションの開始: `IDBDatabase`
* トランザクションの使用: `IDBTransaction`
* キーの範囲の設定: `IDBKeyRange`
* データの取得と変更: `IDBObjectStore`
* カーソルの使用: `IDBCursor`
* リファレンス例: To-do Notifications (動く例を見る)


IDBCursor.continue() - Web API

IDBCursor.continue()
====================

**`continue()`** は `IDBCursor` インターフェースのメソッドで、カーソルを現在の方向に次の位置、任意のキーパラメーターに一致するキーを持つアイテムまで進めます。キーを指定しない場合、カーソルはその方向に基づいて、すぐ隣の位置へ進みます。

**注:** この機能は Web Worker 内で利用可能です

構文
--

```js
cursor.continue(key);
```

### 引数

`key` 省略可

カーソルを進めるためのキーです。

### 例外

このメソッドは次の内いずれかの `DOMException` を発生させることがあります。

| 例外 | 解説 |
| --- | --- |
| `TransactionInactiveError` | この `IDBCursor` のトランザクションがアクティブではありません。 |
| `DataError` | キーパラメーターが以下の状態のうちのいずれかである可能性があります。* キーが妥当なキーではない
* キーがこのカーソルの位置と同じかそれより小さく、カーソルの方向が
 `next` または `nextunique` である
* キーがこのカーソルの位置と同じかそれより大きく、カーソルの方向が
 `prev` または `prevunique` である
 |
| `InvalidStateError` | カーソルが現在走査中または末尾を越えて走査しました。 |

例
-

この単純で部分的な実例ではトランザクションを作り、オブジェクトストアを取得した後、オブジェクトストア内の全ての反復処理するためカーソルを使用しています。カーソルはキーに基づいてデータを選択するには必要ありません。その全てを捕らえることができます。また、それぞれのループ内での繰り返しでカーソルオブジェクトを用い、`cursor.value.foo` とすることで、現在のレコードからカーソルの下のデータを取得できることには注目です。完全な例については IDBCursor の例 (ライブデモを見る) を参照してください。

```js
function displayData() {
  var transaction = db.transaction(["rushAlbumList"], "readonly");
  var objectStore = transaction.objectStore("rushAlbumList");

  objectStore.openCursor().onsuccess = function (event) {
    var cursor = event.target.result;
    if (cursor) {
      var listItem = document.createElement("li");
      listItem.innerHTML = cursor.value.albumTitle + ", " + cursor.value.year;
      list.appendChild(listItem);

      cursor.continue();
    } else {
      console.log("全エントリーを表示しました。");
    }
  };
}
```

仕様書
---

| Specification |
| --- |
| Indexed Database API 3.0 # ref-for-dom-idbcursor-continue① |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

関連情報
----

* IndexedDB の使用
* トランザクションの開始 : `IDBDatabase`
* トランザクションを使う : `IDBTransaction`
* キーの範囲設定 : `IDBKeyRange`
* データの取得と変更 : `IDBObjectStore`
* カーソルを使う : `IDBCursor`
* リファレンス 実例 : To-do Notifications (動く例を見る)


IDBCursor.direction - Web API

IDBCursor.direction
===================

`IDBCursor` インターフェイスの読み取り専用プロパティ **`direction`** は、(たとえば `IDBObjectStore.openCursor` で設定した) カーソルの走査の方向を表す文字列です。取りうる値は、以下の値の節を参照してください。

**注:** この機能は Web Worker 内で利用可能です

値
-

カーソルがデータを走査する方向を表す文字列です。以下の値を取りえます。

`next`

この方向は、カーソルを走査対象の最初で開きます。

`nextunique`

この方向は、カーソルを走査対象の最初で開きます。重複した値を持つキーについては、最初のレコードのみを返します。

`prev`

この方向は、カーソルを走査対象の最後で開きます。

`prevunique`

この方向は、カーソルを走査対象の最後で開きます。重複した値を持つキーについては、最初のレコードのみを返します。

例
-

このシンプルな断片では、トランザクションを作成し、オブジェクトストアを取得し、カーソルを使用してオブジェクトストア内の全レコードを走査します。それぞれの繰り返しにおいて、たとえば以下のようなカーソルの方向を記録します。
```

prev
```

**メモ:** `direction` プロパティは読み取り専用なので、このプロパティを用いてカーソルが動く方向を変えることはできません。カーソルが動く方向は、`IDBObjectStore.openCursor` の第 2 引数で設定します。

カーソルを使う場合、データをキーで選択する必要はなく、単に全て取得できます。また、ループ中のそれぞれの繰り返しにおいて、カーソルオブジェクトが指している現在のレコードからデータを `cursor.value.foo` のようにして取得できます。動く例全体は、IDBCursor example を参照してください。(動く例を見る)

```js
function backwards() {
  list.textContent = "";
  const transaction = db.transaction(["rushAlbumList"], "readonly");
  const objectStore = transaction.objectStore("rushAlbumList");

  objectStore.openCursor(null, "prev").onsuccess = (event) => {
    const cursor = event.target.result;
    if (cursor) {
      const listItem = document.createElement("li");
      listItem.textContent = `${cursor.value.albumTitle}, ${cursor.value.year}`;
      list.appendChild(listItem);

      console.log(cursor.direction);
      cursor.continue();
    } else {
      console.log("エントリーを逆向きに表示しました。");
    }
  };
}
```

仕様書
---

| Specification |
| --- |
| Indexed Database API 3.0 # ref-for-dom-idbcursor-direction① |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

関連情報
----

* IndexedDB の使用
* トランザクションの開始: `IDBDatabase`
* トランザクションの使用: `IDBTransaction`
* キーの範囲の設定: `IDBKeyRange`
* データの取得と変更: `IDBObjectStore`
* カーソルの使用: `IDBCursor`
* リファレンス例: To-do Notifications (動く例を見る)


IDBCursor.key - Web API

IDBCursor.key
=============

`IDBCursor` の読み取り専用プロパティ **`key`** は、カーソルが指しているレコードのキーを返します。カーソルが範囲外の場合は `undefined` になります。カーソルのキーは任意のデータ型になり得ます。

**注:** この機能は Web Worker 内で利用可能です

値
-

任意のデータ型の値です。

例
-

このシンプルな断片では、トランザクションを作成し、オブジェクトストアを取得し、カーソルを用いてオブジェクトストア内の全レコードを走査します。それぞれの繰り返しにおいて、以下のようなカーソルのキーを記録します。(キーである、それぞれの場合ごとのアルバムのタイトルです)

カーソルを用いる場合、データをキーで選択する必要はなく、単に全て取得できます。また、ループ中のそれぞれの繰り返しにおいて、カーソルオブジェクトが指している現在のオブジェクトからデータを `cursor.value.foo` のようにして取得できます。動く例全体は、IDBCursor example を参照してください。(動く例を見る)

```js
function displayData() {
  const transaction = db.transaction(["rushAlbumList"], "readonly");
  const objectStore = transaction.objectStore("rushAlbumList");

  objectStore.openCursor().onsuccess = (event) => {
    const cursor = event.target.result;
    if (cursor) {
      const listItem = document.createElement("li");
      listItem.textContent = `${cursor.value.albumTitle}, ${cursor.value.year}`;
      list.appendChild(listItem);

      console.log(cursor.key);
      cursor.continue();
    } else {
      console.log("全エントリーを表示しました。");
    }
  };
}
```

仕様書
---

| Specification |
| --- |
| Indexed Database API 3.0 # ref-for-dom-idbcursor-key① |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

関連情報
----

* IndexedDB の使用
* トランザクションの開始: `IDBDatabase`
* トランザクションの使用: `IDBTransaction`
* キーの範囲の設定: `IDBKeyRange`
* データの取得と変更: `IDBObjectStore`
* カーソルの使用: `IDBCursor`
* リファレンス例: To-do Notifications (動く例を見る)


IDBCursor.advance() - Web API

IDBCursor.advance()
===================

`IDBCursor` インターフェイスの **`advance()`** メソッドはカーソルが位置を前進させる回数をセットします。

**注:** この機能は Web Worker 内で利用可能です

構文
--

```js
cursor.advance(count);
```

### 引数

`count`

カーソルが前進する回数

### 返値

`undefined`### 例外

このメソッドは次のいずれかの `DOMException` を発生することがあります:

| 例外 | 説明 |
| --- | --- |
| `TransactionInactiveError` | この `IDBCursor` のトランザクションは活性化していません。 |
| `TypeError` | `count` パラメーターに渡された値がゼロや負の数です。 |
| `InvalidStateError` | カーソルは現在繰り返し中か、最後を過ぎています。 |

例
-

このシンプルな断片でトランザクションを作成し、オブジェクトストアを取得し、オブジェクトストアのレコードを一通り繰り返すカーソルを使っています。ここで `cursor.advance(2)` を使ってそれぞれ 2 回前進していて、つまり 1 つおきの結果だけが表示されます。`advance()` は `IDBCursor.continue` と同様に動作しますが、常に次のレコードに移動するのでなく、一度に複数のレコードを飛び越えられるのが違います。

注意点としてループの繰り返しで、カーソルオブジェクトの現在のレコードのテータを `cursor.value.foo`を使って取得できます。完全な動作例は、IDBCursor の例(ライブ例を見る)を見てください。

```js
function advanceResult() {
  list.innerHTML = "";
  var transaction = db.transaction(["rushAlbumList"], "readonly");
  var objectStore = transaction.objectStore("rushAlbumList");

  objectStore.openCursor().onsuccess = function (event) {
    var cursor = event.target.result;
    if (cursor) {
      var listItem = document.createElement("li");
      listItem.innerHTML =
        "<strong>" +
        cursor.value.albumTitle +
        "</strong>, " +
        cursor.value.year;
      list.appendChild(listItem);
      cursor.advance(2);
    } else {
      console.log("全エントリーを 1 つおきに表示しました。");
    }
  };
}
```

仕様書
---

| Specification |
| --- |
| Indexed Database API 3.0 # ref-for-dom-idbcursor-advance① |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

関連情報
----

* IndexedDB を使用する
* トランザクションを開始する : `IDBDatabase`
* トランザクションを使用する : `IDBTransaction`
* キーレンジを設定する : `IDBKeyRange`
* データの取得と変更 : `IDBObjectStore`
* カーソルを使用する : `IDBCursor`
* リファレンスの例 : To-do Notifications (ライブ例を見る)


Event: type プロパティ - Web API

Event: type プロパティ
=================

**`type`** は `Event` インターフェイスの読み取り専用プロパティで、イベントの種別を表す文字列を返します。イベントが構築されると設定され、この名前は `click`, `load`, `error` のような特定のイベントを参照するためによく使用されます。

値
-

`Event` の種別を表す文字列です。

例
-

この例は、キーボードのキーを押すか、マウスボタンをクリックするとイベント種別をログに出力します。

### HTML

```html
<p>キーを押すか、マウスをクリックしてください。</p>
<p id="log"></p>
```

### JavaScript

```js
function getEventType(event) {
  const log = document.getElementById("log");
  log.innerText = `${event.type}\n${log.innerText}`;
}

// キーボードイベント
document.addEventListener("keydown", getEventType, false); // first
document.addEventListener("keypress", getEventType, false); // second
document.addEventListener("keyup", getEventType, false); // third

// マウスイベント
document.addEventListener("mousedown", getEventType, false); // first
document.addEventListener("mouseup", getEventType, false); // second
document.addEventListener("click", getEventType, false); // third
```

### 結果

仕様書
---

| Specification |
| --- |
| DOM Standard # ref-for-dom-event-type④ |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

関連情報
----

* `EventTarget.addEventListener()`
* `EventTarget.removeEventListener()`


Event: cancelBubble プロパティ - Web API

Event: cancelBubble プロパティ
=========================

**非推奨:** この機能は非推奨になりました。まだ対応しているブラウザーがあるかもしれませんが、すでに関連するウェブ標準から削除されているか、削除の手続き中であるか、互換性のためだけに残されている可能性があります。使用を避け、できれば既存のコードは更新してください。このページの下部にある互換性一覧表を見て判断してください。この機能は突然動作しなくなる可能性があることに注意してください。

**`cancelBubble`** は `Event` インターフェイスのプロパティで、非推奨です。代わりに `Event.stopPropagation()` を使用してください。
 イベントハンドラーから戻る前にこの値を `true` に設定すると、イベントの伝播を防ぐことができます。それ以降の実装では、この値を `false` に設定しても何も起こりません。
 詳しくはブラウザーの互換性を参照してください。

値
-

論理値です。 `true` の値は、イベントがこれ以上伝播しないことを意味します。

例
-

```js
elem.onclick = (event) => {
  // Do cool things here
  event.cancelBubble = true;
};
```

仕様書
---

| Specification |
| --- |
| DOM Standard # ref-for-dom-event-cancelbubble① |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


イベントターゲットの比較 - Web API

イベントターゲットの比較
============

イベントハンドラーを書くときに、どのイベントターゲットを調べればいいのか迷うことはよくあります。この記事では、ターゲットプロパティの使い方を明確にします。

検討すべきターゲットは 5 つあります。

| プロパティ | 定義場所 | 目的 |
| --- | --- | --- |
| `event.target` | DOM Event Interface | このイベントを発行した呼び出しの左側にある DOM 要素。 |
| `event.currentTarget` | DOM Event Interface | その `EventListeners` が現在処理されている `EventTarget` です。イベントキャプチャとバブリングが発生すると、この値は変化します。 |
| `event.relatedTarget` | DOM MouseEvent Interface | イベントのセカンダリーターゲットを特定します。 |
| `event`.explicitOriginalTarget`` | Event.webidl |
Non-standard
 イベントが無名の境界通過以外の理由で再ターゲットされた場合、再ターゲットが発生する前にターゲットに設定されます。例えば、マウスイベントがテキストノードの上で発生した場合、その親ノードに再ターゲットされます（[Firefox バグ 185889](https://bugzil.la/185889)）。その場合、 `.target` は親ノードを表示し、`.explicitOriginalTarget` はテキストノードを表示します。
 `.originalTarget` とは異なり、`.explicitOriginalTarget` には無名コンテンツが含まれることはありません。
  |
| `event.originalTarget` | Event.webidl |
Non-standard
 再ターゲットされる前の、イベントの本来のターゲットです。詳細は Anonymous Content#Event\_Flow\_and\_Targeting を参照してください。 |
| event.composedTarget | Event.webidl |
Non-standard
 Shadow DOM から合成する前の、イベントの元の非ネイティブターゲット。 |

### `explicitOriginalTarget` と `originalTarget` の使用

**メモ:** これらのプロパティは、 Mozilla ベースのブラウザーでのみ利用可能です。

### 例

```html
<!doctype html>
<html lang="en-US">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <title>Comparison of Event Targets</title>
    <style>
 table {
 border-collapse: collapse;
 height: 150px;
 width: 100%;
 }
 td {
 border: 1px solid #ccc;
 font-weight: bold;
 padding: 5px;
 min-height: 30px;
 }
 .standard {
 background-color: #99ff99;
 }
 .non-standard {
 background-color: #902d37;
 }
 </style>
  </head>
  <body>
    <table>
      <thead>
        <tr>
          <td class="standard">
            Original target dispatching the event <small>event.target</small>
          </td>
          <td class="standard">
            Target who's event listener is being processed
            <small>event.currentTarget</small>
          </td>
          <td class="standard">
            Identify other element (if any) involved in the event
            <small>event.relatedTarget</small>
          </td>
          <td class="non-standard">
            If there was a retargeting of the event for some reason
            <small> event.explicitOriginalTarget</small> contains the target
            before retargeting (never contains anonymous targets)
          </td>
          <td class="non-standard">
            If there was a retargeting of the event for some reason
            <small> event.originalTarget</small> contains the target before
            retargeting (may contain anonymous targets)
          </td>
        </tr>
      </thead>
      <tr>
        <td id="target"></td>
        <td id="currentTarget"></td>
        <td id="relatedTarget"></td>
        <td id="explicitOriginalTarget"></td>
        <td id="originalTarget"></td>
      </tr>
    </table>
    <p>
      Clicking on the text will show the difference between
      explicitOriginalTarget, originalTarget, and target
    </p>
    <script>
 function handleClicks(e) {
 document.getElementById("target").innerHTML = e.target;
 document.getElementById("currentTarget").innerHTML = e.currentTarget;
 document.getElementById("relatedTarget").innerHTML = e.relatedTarget;
 document.getElementById("explicitOriginalTarget").innerHTML =
 e.explicitOriginalTarget;
 document.getElementById("originalTarget").innerHTML = e.originalTarget;
 }

 function handleMouseover(e) {
 document.getElementById("target").innerHTML = e.target;
 document.getElementById("relatedTarget").innerHTML = e.relatedTarget;
 }

 document.addEventListener("click", handleClicks, false);
 document.addEventListener("mouseover", handleMouseover, false);
 </script>
  </body>
</html>
```

### `target` と `relatedTarget` の使用

`mouseover` イベントの `relatedTarget` プロパティは、マウスが以前乗っていたノードを保持します。 `mouseout` イベントでは、マウスが移動した先のノードが保持されます。

| イベント種別 | event.target | event.relatedTarget |
| --- | --- | --- |
| `mouseover` | ポインティングデバイスが入った EventTarget | ポインティングデバイスが出た EventTarget |
| `mouseout` | ポインティングデバイスが出た EventTarget | ポインティングデバイスが入った EventTarget |

#### 例

```xml
<hbox id="outer">
  <hbox id="inner"
 onmouseover="dump('mouseover ' + event.relatedTarget.id + ' > ' + event.target.id + '\n');"
 onmouseout="dump('mouseout ' + event.target.id + ' > ' + event.relatedTarget.id + '\n');"
 style="margin: 100px; border: 10px solid black; width: 100px; height: 100px;" />
</hbox>
```


Event: preventDefault() メソッド - Web API

Event: preventDefault() メソッド
============================

**`preventDefault()`** は `Event` インターフェイスのメソッドで、ユーザーエージェントに、このイベントが明示的に処理されない場合に、その既定のアクションを通常どおりに行うべきではないことを伝えます。

このイベントは通常、イベントリスナーの 1 つが `stopPropagation()` または `stopImmediatePropagation()` を呼び出し、いずれかが一度に伝播を終了しない限り、伝播し続けます。

後述のように、 **`preventDefault()`** を `EventTarget.dispatchEvent()` によってディスパッチされたイベントのようなキャンセルできないイベントに対して、 `cancelable: true` を指定せずに呼び出しても何も効果がありません。

構文
--

```js
event.preventDefault()
```

例
-

### 既定のクリック処理のブロック

チェックボックスのクリック時、既定の動作ではチェックボックスが切り替わります。この既定の動作を止める方法を以下に示します。

#### JavaScript

```js
const checkbox = document.querySelector("#id-checkbox");

checkbox.addEventListener("click", checkboxClick, false);

function checkboxClick(event) {
  let warn = "preventDefault() がこのチェックを妨害しています。<br>";
  document.getElementById("output-box").innerHTML += warn;
  event.preventDefault();
}
```

#### HTML

```html
<p>チェックボックスコントロールをクリックしてください。</p>

<form>
  <label for="id-checkbox">チェックボックス:</label>
  <input type="checkbox" id="id-checkbox" />
</form>

<div id="output-box"></div>
```

#### 結果

### キーストロークが編集フィールドに到達するのを止める

次の例は、無効なテキスト入力が入力フィールドに到達するのを `preventDefault()` で止める方法を示しています。今日では、ネイティブの HTML フォーム検証を代わりに使用してください。

#### HTML

 下の HTML フォームはユーザーの入力をキャプチャします。
 キー入力にしか興味がないので、`autocomplete` を無効にして、ブラウザーがキャッシュした値で入力フィールドを埋めるのを防いでいます。

```html
<div class="container">
  <p>名前を小文字のみで入力してください。</p>

  <form>
    <input type="text" id="my-textbox" autocomplete="off" />
  </form>
</div>
```

#### CSS

ユーザが無効なキーを押したときに描画する警告ボックスには、CSS を少し使用します。

```css
.warning {
  border: 2px solid #f39389;
  border-radius: 2px;
  padding: 10px;
  position: absolute;
  background-color: #fbd8d4;
  color: #3b3c40;
}
```

#### JavaScript

そして、こちらがその仕事を行う JavaScript コードです。まず、`keydown` イベントを待ち受けします。

```js
const myTextbox = document.getElementById("my-textbox");
myTextbox.addEventListener("keydown", checkName, false);
```

`checkName()` 関数は押されたキーを調べ、それを許可するかどうかを決定します。

```js
function checkName(evt) {
  const key = evt.key;
  const lowerCaseAlphabet = "abcdefghijklmnopqrstuvwxyz";
  if (!lowerCaseAlphabet.includes(key)) {
    evt.preventDefault();
    displayWarning(
      "小文字のみを使用してください。\n" + `押されたキー: ${key}\n`,
    );
  }
}
```

`displayWarning()` 関数は、問題発生の通知を表示します。これはエレガントな関数ではありませんが、この例の目的には十分です。

```js
let warningTimeout;
const warningBox = document.createElement("div");
warningBox.className = "warning";

function displayWarning(msg) {
  warningBox.innerHTML = msg;

  if (document.body.contains(warningBox)) {
    clearTimeout(warningTimeout);
  } else {
    // insert warningBox after myTextbox
    myTextbox.parentNode.insertBefore(warningBox, myTextbox.nextSibling);
  }

  warningTimeout = setTimeout(() => {
    warningBox.parentNode.removeChild(warningBox);
    warningTimeout = -1;
  }, 2000);
}
```

#### 結果

メモ
--

イベントフローのいずれかの段階でイベントをキャンセルする途中で `preventDefault()` を呼び出すと、通常はブラウザーの実装によって処理される既定のアクションが動作しなくなり、結果としてイベントが発生しなくなります。

イベントがキャンセル可能かどうかは `event.cancelable` を使って確認できます。キャンセル不可のイベントに対して `preventDefault()` を呼び出しても効果はありません。

仕様書
---

| Specification |
| --- |
| DOM Standard # ref-for-dom-event-preventdefault③ |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


Event: explicitOriginalTarget プロパティ - Web API

Event: explicitOriginalTarget プロパティ
===================================

**非標準:** この機能は標準ではなく、標準化の予定もありません。公開されているウェブサイトには使用しないでください。ユーザーによっては使用できないことがあります。実装ごとに大きな差があることもあり、将来は振る舞いが変わるかもしれません。

**`explicitOriginalTarget`** は `Event` インターフェイスの読み取り専用プロパティで、このイベントの無名ではない元のターゲットを返します。

イベントが無名境界通過以外の何らかの理由で再ターゲットされた場合、再ターゲットが発生する前にターゲットに設定されます。

例えば、マウスイベントがテキストノードの上で発生した場合、その親ノードに再ターゲットされます（Webkit バグ 185889 参照）。この場合、 `currentTarget` は親ノードを表示し、このプロパティはテキストノードを表示することになります。

このプロパティは `originalTarget` とも異なり、無名のコンテンツを含むことはありません。

値
-

`EventTarget` オブジェクトを返します。ない場合は null を返します。

例
-

このプロパティは `<command>` と共に使用すると、コマンドを呼び出した元のオブジェクトのイベントの詳細を取得することができます。

```js
function myCommand(ev) {
  alert(ev.explicitOriginalTarget.nodeName); // returns 'menuitem'
}
```

```xml
<xul:command id="my-cmd-anAction" oncommand="myCommand(event);"/>

<xul:menulist>
  <xul:menupopup>
    <xul:menuitem label="Get my element name!" command="my-cmd-anAction"/>
  </xul:menupopup>
</menulist>
```

仕様書
---

*これは Mozilla 固有のプロパティであり、現在のどの仕様にも含まれていません。標準化される予定もありません。*

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

関連情報
----

* イベントターゲットの比較


Event: stopImmediatePropagation() メソッド - Web API

Event: stopImmediatePropagation() メソッド
======================================

**`stopImmediatePropagation()`** は `Event` インターフェイスのメソッドで、呼び出されている同じイベントの他のリスナーを抑止します。

同じ要素で、同じ種類のイベントに複数のリスナーが装着されている場合、追加された順番に呼び出されます。もし、そのような呼び出しの最中に `stopImmediatePropagation()` が呼び出された場合、残りのリスナーは呼び出されなくなります。

構文
--

```js
event.stopImmediatePropagation()
```

例
-

### イベントを停止する関数の比較

下の例では、3 つの入れ子になった div の中に 3 つのボタンがあります。それぞれのボタンにはクリックイベント用に登録された 3 つのイベントリスナーがあり、それぞれの div にもクリックイベント用に登録されたイベントリスナーがあります。

* 一番上のボタンは、通常のイベント伝播が可能です。
* 中央のボタンは、最初のイベントハンドラーで `stopPropagation()` を呼び出します。
* 一番下のボタンは、最初のイベントハンドラーで `stopImmediatePropagation()` を呼び出します。

#### HTML

```html
<h2>ボタンをクリックしてください</h2>
<div>
  外側の div<br />
  <div>
    中央の div<br />
    <div>
      内側の div<br />
      <button>伝播可能</button><br />
      <button id="stopPropagation">伝播を停止</button><br />
      <button id="stopImmediatePropagation">直ちに伝播を停止</button>
    </div>
  </div>
</div>
<pre></pre>
```

#### CSS

```css
div {
  display: inline-block;
  padding: 10px;
  background-color: #fff;
  border: 2px solid #000;
  margin: 10px;
}

button {
  width: 100px;
  color: #008;
  padding: 5px;
  background-color: #fff;
  border: 2px solid #000;
  border-radius: 30px;
  margin: 5px;
}
```

#### JavaScript

```js
const outElem = document.querySelector("pre");

/\* Clear the output \*/
document.addEventListener(
  "click",
  () => {
    outElem.textContent = "";
  },
  true,
);

/\* Set event listeners for the buttons \*/
document.querySelectorAll("button").forEach((elem) => {
  for (let i = 1; i <= 3; i++) {
    elem.addEventListener("click", (evt) => {
      /\* 最初のイベントハンドラーですべての伝播を停止 \*/
      if (i === 1 && elem.id) {
        evt[elem.id]();
        outElem.textContent += `イベント 1 のイベントハンドラーが ${elem.id}() を呼び出しました\n`;
      }

      outElem.textContent += `"${elem.textContent}" ボタンのクリックイベント ${i} が処理されました\n`;
    });
  }
});

/\* それぞれの div にイベントリスナーを設定 \*/
document
  .querySelectorAll("div")
  .forEach((elem) =>
    elem.addEventListener(
      "click",
      (evt) =>
        (outElem.textContent += `"${elem.firstChild.data.trim()}" でクリックイベントが処理されました\n`),
    ),
  );
```

#### 結果

それぞれのクリックイベントハンドラーは、呼び出されるとステータスメッセージを表示します。中央のボタンを押すと、`stopPropagation()` によって、そのボタンがクリックされたときに登録されたイベントハンドラはすべて実行されますが、その後に続くはずの div のクリックイベントハンドラーは実行されないことがわかります。しかし、一番下のボタンを押すと、`stopImmediatePropagation()` はそのイベント以降の伝播をすべて停止します。

仕様書
---

| Specification |
| --- |
| DOM Standard # ref-for-dom-event-stopimmediatepropagation① |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


Event: composedPath() メソッド - Web API

Event: composedPath() メソッド
==========================

Baseline Widely available
-------------------------

This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020.

* Learn more
* See full compatibility
* Report feedback
**`composedPath()`** は `Event` インターフェイスのメソッドで、イベントの経路をリスナーが呼び出されるオブジェクトの配列で返します。シャドウルートが `ShadowRoot.mode` が closed の状態で作成された場合、シャドウツリーのノードは含まれません。

構文
--

```js
const composed = Event.composedPath()
```

### 引数

なし。

### 返値

`EventTarget` オブジェクトの配列で、イベントリスナーが呼び出される予定の一連のオブジェクトを表します。

例
-

次の例は、 https://mdn.github.io/web-components-examples/composed-composed-path/ を試すもので、`<open-shadow>` と `<closed-shadow>` という 2 つの些細なカスタム要素を定義しています。どちらも text 属性の内容を `<p>` 要素のテキストコンテンツとして、要素のシャドウ DOM に挿入します。両者の唯一の違いは、シャドウルートがそれぞれ `open` と `closed` に設定された状態で取り付けられることです。

```js
customElements.define(
  "open-shadow",
  class extends HTMLElement {
    constructor() {
      super();

      const pElem = document.createElement("p");
      pElem.textContent = this.getAttribute("text");

      const shadowRoot = this.attachShadow({ mode: "open" });
      shadowRoot.appendChild(pElem);
    }
  },
);

customElements.define(
  "closed-shadow",
  class extends HTMLElement {
    constructor() {
      super();

      const pElem = document.createElement("p");
      pElem.textContent = this.getAttribute("text");

      const shadowRoot = this.attachShadow({ mode: "closed" });
      shadowRoot.appendChild(pElem);
    }
  },
);
```

それからそれぞれの要素を 1 つずつをページに挿入します。

```html
<open-shadow text="I have an open shadow root"></open-shadow>
<closed-shadow text="I have a closed shadow root"></closed-shadow>
```

それから click イベントリスナーを `<html>` 要素に設定します。

```js
document.querySelector("html").addEventListener("click", (e) => {
  console.log(e.composed);
  console.log(e.composedPath());
});
```

まず `<open-shadow>` 要素をクリックし、次に `<closed-shadow>` 要素をクリックすると、 2 つのことに気がつきます。第 1 に、`click` イベントは常にシャドウの境界を越えて伝搬することができるため、`composed` プロパティは `true` を返します。第 2 に、 2 つの要素の `composedPath` の値に違いがあります。

`<open-shadow>` 要素の合成パスは次の通りです。
```

Array [ p, ShadowRoot, open-shadow, body, html, HTMLDocument https://mdn.github.io/web-components-examples/composed-composed-path/, Window ]
```

それに対して `<closed-shadow>` 要素の合成パスは次の通りです。
```

Array [ closed-shadow, body, html, HTMLDocument https://mdn.github.io/web-components-examples/composed-composed-path/, Window ]
```

2 番目の場合、イベントリスナーは `<closed-shadow>` 要素自身までしか伝搬せず、シャドウ境界の内側のノードには伝搬しません。

仕様書
---

| Specification |
| --- |
| DOM Standard # ref-for-dom-event-composedpath① |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


Event: target プロパティ - Web API

Event: target プロパティ
===================

**`target`** は `Event` インターフェイスの読み取り専用プロパティで、イベントが配信されたオブジェクトへの参照です。これは、イベントのバブリングまたはキャプチャ段階でイベントハンドラーが呼び出されたときの `Event.currentTarget` とは異なります。

値
-

関連する `EventTarget` です。

例
-

`event.target` プロパティは、**イベントデリゲーション**を実装するために使用できます。

```js
// リストの作成
const ul = document.createElement("ul");
document.body.appendChild(ul);

const li1 = document.createElement("li");
const li2 = document.createElement("li");
ul.appendChild(li1);
ul.appendChild(li2);

function hide(evt) {
  // evt.target はクリックされた <li> 要素を参照しています。
  // これはこのコンテキストで親である <ul> を参照している evt.currentTarget とは異なります。
  evt.target.style.visibility = "hidden";
}

// リストにリスナーを接続します
// <li> がクリックされた時に発行されます。
ul.addEventListener("click", hide, false);
```

仕様書
---

| Specification |
| --- |
| DOM Standard # ref-for-dom-event-target③ |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

関連情報
----

* イベントターゲットの比較


Event: initEvent() メソッド - Web API

Event: initEvent() メソッド
=======================

**非推奨:** この機能は非推奨になりました。まだ対応しているブラウザーがあるかもしれませんが、すでに関連するウェブ標準から削除されているか、削除の手続き中であるか、互換性のためだけに残されている可能性があります。使用を避け、できれば既存のコードは更新してください。このページの下部にある互換性一覧表を見て判断してください。この機能は突然動作しなくなる可能性があることに注意してください。

**`Event.initEvent()`** メソッドは、 `Document.createEvent()` を使用して作成されたイベント (`event`) の値を初期化するために使用します。

 この方法で初期化されたイベントは、 `Document.createEvent()` メソッドで作成されている必要があります。
 このメソッドは `EventTarget.dispatchEvent()` を使用してイベントが配信される前に、イベントを設定するために呼び出す必要があります。
 配信されると、もう何もしません。

**メモ:** **このメソッドは廃止されているため、使用しないでください。**
 代わりに、 `Event()` のような特定のイベントのコンストラクターを使用してください。イベントの作成と起動のページに、これらの使用方法の詳細が記載されています。

構文
--

```js
event.initEvent(type, bubbles, cancelable)
```

### 引数

`type`

文字列で、イベントの種類を定義します。

`bubbles`

論理値で、イベントがイベントチェーンを通じてバブルアップするかどうかを決定します。設定されると、読み取り専用のプロパティ `Event.bubbles` がその値を提供します。

`cancelable`

論理値で、イベントをキャンセルできるかどうかを定義します。設定されると、読み取り専用のプロパティ `Event.cancelable` がその値を提供します。

### 返値

なし。

例
-

```js
// イベントを作成
const event = document.createEvent("Event");

// バブルアップしキャンセルできないクリックイベントを
// 作成
event.initEvent("click", true, false);

// イベントを待ち受けする
elem.addEventListener(
  "click",
  (e) => {
    // e.target が elem と一致
  },
  false,
);

elem.dispatchEvent(event);
```

仕様書
---

| Specification |
| --- |
| DOM Standard # ref-for-dom-event-initevent① |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

関連情報
----

* この非推奨のメソッドの代わりに使用するコンストラクター:
 `Event()`。より具体的なイベントインターフェイスを作成するには、目的のイベントインターフェイスに対して定義されたコンストラクターを使用します。


Event: Event() コンストラクター - Web API

Event: Event() コンストラクター
=======================

**`Event()`** コンストラクターは、新しい `Event` を生成します。この方法で作成されたイベントは*合成イベント*と呼ばれ、ブラウザーによって発行されたイベントとは対照的となっており、スクリプトから配信することができます。

構文
--

```js
new Event(type)
new Event(type, options)
```

### 値

`type`

文字列で、イベントの名前を表します。

`options` 省略可

以下のプロパティを持ったオブジェクトです。

`bubbles`

論理値で、イベントがバブリングするかどうかを示します。既定値は `false` です。

`cancelable`

論理値で、イベントがキャンセル可能かどうかを示します。既定値は `false` です。

`composed`

論理値で、イベントがシャドウルートの外のリスナーに伝わるかどうかを示します（詳しくは `Event.composed` を参照してください）。既定値は `false` です。

### 返値

新しい `Event` オブジェクトです。

例
-

```js
// バブルアップし、キャンセルできない look イベントを作成

const evt = new Event("look", { bubbles: true, cancelable: false });
document.dispatchEvent(evt);

// イベントは文書だけでなく、あらゆる要素から配信することができる
myDiv.dispatchEvent(evt);
```

仕様書
---

| Specification |
| --- |
| DOM Standard # ref-for-dom-event-event |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

関連情報
----

* `Event`
* `EventTarget.dispatchEvent()`
* イベントの作成とトリガー


Event: currentTarget プロパティ - Web API

Event: currentTarget プロパティ
==========================

**`currentTarget`** は `Event` インターフェイスの読み取り専用プロパティで、イベントが DOM を走査する際の、イベントの現在のターゲットを特定します。これは常にイベントハンドラーが装着されている要素を指し、`Event.target` とは対照的に、イベントが発生した要素やその子孫である可能性のある要素を特定します。

値
-

`EventTarget` で、現在のイベントハンドラーが装着されているオブジェクトを表します。

例
-

`Event.currentTarget` は、複数の要素に同じイベントハンドラーを割り当てるときに使用すると面白いです。

```js
function hide(e) {
  e.currentTarget.style.visibility = "hidden";
  console.log(e.currentTarget);
  // この関数がイベントハンドラーとして使用されるとき： this === e.currentTarget
}

const ps = document.getElementsByTagName("p");

for (const p of ps) {
  // クリックされた <p> 要素を隠す
  p.addEventListener("click", hide, false);
}

document.body.addEventListener("click", hide, false);

// 周辺をクリックすると段落が消えます。
```

**メモ:** イベント処理中*だけ* `event.currentTarget` の値は利用可能です。
 もし `console.log()` で `event` オブジェクトを変数に格納し、コンソールで `currentTarget` キーを探すと、その値は `null` となります
 `console.log(event.currentTarget)` を使ってコンソールで表示するか、 `debugger` 文を使ってコードの実行を一時停止し、 `event.currentTarget` の値を表示させる必要があります。

仕様書
---

| Specification |
| --- |
| DOM Standard # ref-for-dom-event-currenttarget② |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

関連情報
----

* イベントターゲットの比較


Event: bubbles プロパティ - Web API

Event: bubbles プロパティ
====================

**`bubbles`** は `Event` インターフェイスの読み取り専用プロパティで、イベントが DOM ツリーをバブリングするかしないかを示します。

**メモ:** バブリングについての詳細は、イベントのバブリングとキャプチャを参照してください。

値
-

論理値で、このイベントが DOM ツリーをバブリングするのであれば `true` です。

例
-

```js
function handleInput(e) {
  // バブリングするイベントを渡すかどうかをチェック
  if (!e.bubbles) {
    passItOn(e);
  }

  // 既にバブリングした
  doOutput(e);
}
```

仕様書
---

| Specification |
| --- |
| DOM Standard # ref-for-dom-event-bubbles③ |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

関連情報
----

* `stopPropagation()` はイベントのバブリングを停止します
* `stopImmediatePropagation()` は同じイベントが DOM 内の同じ水準で他のリスナーを呼び出すことを抑止します
* `preventDefault()` は拡散を続けることを許可しますが、ブラウザーがイベントを扱うためのリスナーがない既定のアクションを実行することを許可しません


Event: isTrusted プロパティ - Web API

Event: isTrusted プロパティ
======================

**`isTrusted`** は `Event` インターフェイスの読み取り専用プロパティで、このイベントがユーザー操作によって生成された場合は `true`、このイベントがスクリプトで作成または変更されたり、 `EventTarget.dispatchEvent()` で配信されたりした場合は `false` となる論理値を返します。

値
-

論理値です。

例
-

```js
if (e.isTrusted) {
  /\* このイベントは信頼されている \*/
} else {
  /\* このイベントは信頼されていない \*/
}
```

仕様書
---

| Specification |
| --- |
| DOM Standard # ref-for-dom-event-istrusted① |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


Event: returnValue プロパティ - Web API

Event: returnValue プロパティ
========================

**非推奨:** この機能は非推奨になりました。まだ対応しているブラウザーがあるかもしれませんが、すでに関連するウェブ標準から削除されているか、削除の手続き中であるか、互換性のためだけに残されている可能性があります。使用を避け、できれば既存のコードは更新してください。このページの下部にある互換性一覧表を見て判断してください。この機能は突然動作しなくなる可能性があることに注意してください。

`Event` の **`returnValue`** は、このイベントの既定のアクションが禁止されているかどうかを示します。

既定では `true` で、既定のアクションを実行してもよいことを表します。このプロパティを `false` に設定すると、既定のアクションを阻止します。

**メモ:** `returnValue` は DOM 標準に採用されましたが、主に既存のコードをサポートするために存在しています。この古いなプロパティの代わりに `preventDefault()` と `defaultPrevented` を使用してください。

値
-

論理値で、イベントがキャンセルされていない場合は `true` となります。そうでない場合、イベントがキャンセルされたか、既定のアクションが阻止された場合に `false` となります。

`returnValue` の値は `defaultPrevented` が返す値とは逆の値になります。

仕様書
---

| Specification |
| --- |
| DOM Standard # dom-event-returnvalue |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

関連情報
----

* `HTMLDialogElement.returnValue`: `<dialog>` の返値


Event: timeStamp プロパティ - Web API

Event: timeStamp プロパティ
======================

**`timeStamp`** は `Event` インターフェイスの読み取り専用プロパティで、イベントが作成された時刻（ミリ秒単位）を返します。

値
-

 この値は、時間の起点からイベントが作成されるまでの経過ミリ秒数です。
 グローバルオブジェクトが `Window` である場合、ユーザーがリンクをクリックした瞬間、または文書の読み込みを開始したスクリプトが時間の起点となります。
 ワーカーでは、時間の起点はワーカーが作成された瞬間となります。

値は、5 マイクロ秒（0.005 ミリ秒）精度の `DOMHighResTimeStamp` ですが、[フィンガープリンティング(/ja/docs/Glossary/Fingerprinting)を防ぐために精度が落とされています。

例
-

### HTML

```html
<p>
  この iframe にフォーカスを設定していずれかのキーを押下すると、 keypress
  イベントの現在のタイムスタンプを取得します。
</p>
<p>timeStamp: <span id="time">-</span></p>
```

### JavaScript

```js
function getTime(event) {
  const time = document.getElementById("time");
  time.firstChild.nodeValue = event.timeStamp;
}
document.body.addEventListener("keypress", getTime);
```

### 結果

時間精度の低下
-------

タイミング攻撃やフィンガープリントに対する保護を提供するために、`Event.timeStamp` の精度はブラウザーの設定によって丸められていることがあります。

Firefox では、`privacy.reduceTimerPrecision` 環境設定が既定で有効になっており、既定値は 2 ミリ秒になっています。

```js
// Firefox での時間精度の低下（既定: 2 ミリ秒）
event.timeStamp;
// 9934
// 10362
// 11670
// …
```

Firefox では、 `privacy.resistFingerprinting` も有効にすると、精度は 100 ミリ秒または `privacy.resistFingerprinting.reduceTimerPrecision.microseconds` の値のうち大きい方になります。

仕様書
---

| Specification |
| --- |
| DOM Standard # ref-for-dom-event-timestamp① |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


Event: stopPropagation() メソッド - Web API

Event: stopPropagation() メソッド
=============================

**`stopPropagation()`** は `Event` インターフェイスのメソッドで、キャプチャおよびバブリング段階において現在のイベントのさらなる伝播を阻止します。しかし、これは既定の動作の発生を妨げるものではありません。例えば、リンクのクリックはまだ処理されます。これらの動作を止めたい場合は、`preventDefault()` メソッドを参照してください。また、現在の要素における他のイベントハンドラーへの伝搬も防げません。それらを止めたい場合は、`stopImmediatePropagation()`　を参照してください。

構文
--

```js
event.stopPropagation()
```

### 引数

なし。

### 返値

なし。

例
-

イベントの伝播 を参照してください。
 `stopImmediatePropagation()` の例も参照してください。

仕様書
---

| Specification |
| --- |
| DOM Standard # ref-for-dom-event-stoppropagation① |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


Event: originalTarget プロパティ - Web API

Event: originalTarget プロパティ
===========================

**非標準:** この機能は標準ではなく、標準化の予定もありません。公開されているウェブサイトには使用しないでください。ユーザーによっては使用できないことがあります。実装ごとに大きな差があることもあり、将来は振る舞いが変わるかもしれません。

**`originalTarget`** は `Event` インターフェイスの読み取り専用プロパティで、このイベントが再ターゲットされる前の下のターゲットを返します。 `Event.explicitOriginalTarget` とは異なり、ネイティブの無名コンテンツになることもあります。

イベントターゲットの比較も参照してください。

仕様書
---

*これは Mozilla 固有のプロパティであり、現在のどの仕様にも含まれていません。標準化される予定もありません。*

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


Event: defaultPrevented プロパティ - Web API

Event: defaultPrevented プロパティ
=============================

**`defaultPrevented`** は `Event` インターフェイスの読み取り専用プロパティで、`Event.preventDefault()` の呼び出しがイベントをキャンセルしたかどうかを示す値を論理値で返します。

値
-

論理値で、 `true` は既定のユーザーエージェントの動作が抑制されたことを、 `false` はそうではないことを表しています。

例
-

この例は 2 つの `<a>` 要素のリンクを訪れる試みをログ出力します。 JavaScript は 2 番目のリンクの動作を抑制するために使用しています。

### HTML

```html
<p><a id="link1" href="#link1">Visit link 1</a></p>
<p><a id="link2" href="#link2">Try to visit link 2</a> (you can't)</p>
<p id="log"></p>
```

### JavaScript

```js
function stopLink(event) {
  event.preventDefault();
}

function logClick(event) {
  const log = document.getElementById("log");

  if (event.target.tagName === "A") {
    log.innerText = event.defaultPrevented
      ? `Sorry, but you cannot visit this link!\n${log.innerText}`
      : `Visiting link…\n${log.innerText}`;
  }
}

const a = document.getElementById("link2");
a.addEventListener("click", stopLink);
document.addEventListener("click", logClick);
```

### 結果

仕様書
---

| Specification |
| --- |
| DOM Standard # ref-for-dom-event-defaultprevented① |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


Event: composed プロパティ - Web API

Event: composed プロパティ
=====================

Baseline Widely available
-------------------------

This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020.

* Learn more
* See full compatibility
* Report feedback
**`composed`** は `Event` インターフェイスの読み取り専用プロパティで、イベントがシャドウ DOM 境界を越えて標準 DOM に伝播するかどうかを示す論理値を返すものです。

UA から送られるすべての UI イベントは合成されます（クリック/タッチ/マウスオーバー/コピー/ペーストなど）。他のほとんどの種類のイベントは合成されないので、`false` を返します。これには、例えば `composed` オプションを `true` に設定せずに作成された合成イベントも含まれます。

伝播は `bubbles` プロパティが `true` である場合にのみ発生します。ただし、合成されたイベントのみをキャプチャした場合は、ホスト側でも `AT_TARGET` フェーズであるかのように処理されます。イベントがシャドウルートを通って DOM ルートに到達するパスを決定するには、 `composedPath()` を呼び出すことで行えます。

値
-

論理値で、イベントがシャドウルート（つまり、シャドウ DOM の中で、イベントが伝播し始めた最初のノード）に到達した後、シャドウ DOM から標準 DOM に伝播する場合は `true` となります。

この値が `false` の場合、シャドウルートはイベントが提供される最後のノードとなります。

例
-

この例では、`<open-shadow>` と `<closed-shadow>` という 2 つの些細なカスタム要素を定義しています。どちらも text 属性の内容を `<p>` 要素のテキストコンテンツとして、要素のシャドウ DOM に挿入します。両者の唯一の違いは、シャドウルートがそれぞれ `open` と `closed` に設定された状態で取り付けられることです。

2 つの定義は次のようになります。

```js
customElements.define(
  "open-shadow",
  class extends HTMLElement {
    constructor() {
      super();

      const pElem = document.createElement("p");
      pElem.textContent = this.getAttribute("text");

      const shadowRoot = this.attachShadow({
        mode: "open",
      });

      shadowRoot.appendChild(pElem);
    }
  },
);

customElements.define(
  "closed-shadow",
  class extends HTMLElement {
    constructor() {
      super();

      const pElem = document.createElement("p");
      pElem.textContent = this.getAttribute("text");

      const shadowRoot = this.attachShadow({
        mode: "closed",
      });

      shadowRoot.appendChild(pElem);
    }
  },
);
```

それからそれぞれの要素を 1 つずつをページに挿入します。

```html
<open-shadow text="I have an open shadow root"></open-shadow>
<closed-shadow text="I have a closed shadow root"></closed-shadow>
```

それから click イベントリスナーを `<html>` 要素に設定します。

```js
document.querySelector("html").addEventListener("click", (e) => {
  console.log(e.composed);
  console.log(e.composedPath());
});
```

まず `<open-shadow>` 要素をクリックし、次に `<closed-shadow>` 要素をクリックすると、 2 つのことに気がつきます。

1. `click` イベントは常にシャドウの境界を越えて伝播することができるため、 `composed` プロパティは `true` を返します。
2. 2 つの要素の `composedPath` の値に違いがあります。

`<open-shadow>` 要素の合成パスは次の通りです。
```

Array [ p, ShadowRoot, open-shadow, body, html, HTMLDocument https://mdn.github.io/web-components-examples/composed-composed-path/, Window ]
```

それに対して `<closed-shadow>` 要素の合成パスは次の通りです。
```

Array [ closed-shadow, body, html, HTMLDocument https://mdn.github.io/web-components-examples/composed-composed-path/, Window ]
```

2 番目の場合、イベントリスナーは `<closed-shadow>` 要素自身までしか伝播せず、シャドウ境界の内側のノードには伝播しません。

仕様書
---

| Specification |
| --- |
| DOM Standard # ref-for-dom-event-composed① |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


Event: srcElement プロパティ - Web API

Event: srcElement プロパティ
=======================

**非推奨:** この機能は非推奨になりました。まだ対応しているブラウザーがあるかもしれませんが、すでに関連するウェブ標準から削除されているか、削除の手続き中であるか、互換性のためだけに残されている可能性があります。使用を避け、できれば既存のコードは更新してください。このページの下部にある互換性一覧表を見て判断してください。この機能は突然動作しなくなる可能性があることに注意してください。

非推奨の **`Event.srcElement`** は `Event.target` プロパティの別名です。代わりに `Event.target` を使用してください。

仕様書
---

| Specification |
| --- |
| DOM Standard # dom-event-srcelement |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

関連情報
----

* `Window.event`


Event: cancelable プロパティ - Web API

Event: cancelable プロパティ
=======================

**`cancelable`** は `Event` インターフェイスの読み取り専用プロパティで、イベントがキャンセル可能かどうか、イベントが発生しないように抑止することができるかを示します。

イベントがキャンセルでき*ない*場合、 `cancelable` プロパティは `false` となり、イベントが発生することをイベントリスナーが抑止することができないことを示します。

ブラウザーネイティブのイベントのうち、キャンセル可能なもののほとんどは、ユーザーのページとの対話の結果から発生したものです。 `click`, `wheel`, `beforeunload` の各イベントをキャンセルすると、それぞれユーザーが何かをクリックすること、ページをスクロールすること、他のページに移動することをそれぞれ抑止することができます。

その他の JavaScript によって作成されたカスタムイベントは、作成時にキャンセル可能であるかどうかを制御します。

イベントをキャンセルするには、そのイベントに対して `preventDefault()` メソッドを呼び出してください。これにより、実装はイベントに関連付けられた既定のアクションを実行しないようになります。

複数の種類のイベントを処理するイベントリスナーは、 `preventDefault()` メソッドを呼び出す前に `cancelable` をチェックしたほうがいいかもしれません。

値
-

論理値で、イベントがキャンセル可能であれば `true` です。

例
-

例えば、ブラウザーベンダーは `wheel` イベントが、最初にリスナーが呼び出されたときのみキャンセル可能にしようと提案しています。 — その後の `wheel` イベントはキャンセルできません。

```js
function preventScrollWheel(event) {
  if (typeof event.cancelable !== "boolean" || event.cancelable) {
    // The event can be canceled, so we do so.
    event.preventDefault();
  } else {
    // The event cannot be canceled, so it is not safe
    // to call preventDefault() on it.
    console.warn(`The following event couldn't be canceled:`);
    console.dir(event);
  }
}

document.addEventListener("wheel", preventScrollWheel);
```

仕様書
---

| Specification |
| --- |
| DOM Standard # ref-for-dom-event-cancelable② |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


Event: eventPhase プロパティ - Web API

Event: eventPhase プロパティ
=======================

**eventPhase`** は `Event` インターフェイスの読み取り専用プロパティは、イベントフローのどの段階が現在評価されているかを示します。

値
-

整数値で、イベントフローの現在の評価段階を指定する値を返します。使用可能な値は以下のとおりです。

`Event.NONE (0)`

現在、このイベントは処理されていません。

`Event.CAPTURING_PHASE (1)`

 イベントはターゲットの祖先オブジェクトを通じて伝播されます。
 この処理は `Window` から始まり、`Document`、`HTMLHtmlElement` と、ターゲットの親に到達するまで要素を介して行われます。
 キャプチャモード向けに `EventTarget.addEventListener()` が呼ばれた時に登録されたイベントリスナーは、この段階で起動されます。

`Event.AT_TARGET (2)`

 このイベントがイベントのターゲットに到達しています。
 この段階向けに登録されたイベントリスナーは、この時点で呼び出されます。もし `Event.bubbles` が `false` ならば、この段階の終了後にイベントの処理を終了します。

`Event.BUBBLING_PHASE (3)`

 イベントはターゲットの祖先を逆順に伝播していきます。親から始まり、最終的に `Window` を含む先祖に到達します。
 これは*バブリング*と呼ばれ、 `Event.bubbles` が `true` のときのみ発生します。この段階向けに登録されたイベントリスナーは、この処理中に起動されます。

例
-

### HTML

```html
<h4>Event Propagation Chain</h4>
<ul>
  <li>Click 'd1'</li>
  <li>Analyze event propagation chain</li>
  <li>Click next div and repeat the experience</li>
  <li>Change Capturing mode</li>
  <li>Repeat the experience</li>
</ul>
<input type="checkbox" id="chCapture" />
<label for="chCapture">Use Capturing</label>
<div id="d1">
  d1
  <div id="d2">
    d2
    <div id="d3">
      d3
      <div id="d4">d4</div>
    </div>
  </div>
</div>
<div id="divInfo"></div>
```

### CSS

```css
div {
  margin: 20px;
  padding: 4px;
  border: thin black solid;
}

#divInfo {
  margin: 18px;
  padding: 8px;
  background-color: white;
  font-size: 80%;
}
```

### JavaScript

```js
let clear = false;
let divInfo = null;
let divs = null;
let chCapture = null;

window.onload = () => {
  divInfo = document.getElementById("divInfo");
  divs = document.getElementsByTagName("div");
  chCapture = document.getElementById("chCapture");
  chCapture.onclick = () => {
    removeListeners();
    addListeners();
    clearDivs();
  };
  clearDivs();
  addListeners();
};

function removeListeners() {
  for (const div of divs) {
    if (div.id !== "divInfo") {
      div.removeEventListener("click", onDivClick, true);
      div.removeEventListener("click", onDivClick, false);
    }
  }
}

function addListeners() {
  for (const div of divs) {
    if (div.id !== "divInfo") {
      if (chCapture.checked) {
        div.addEventListener("click", onDivClick, true);
      } else {
        div.addEventListener("click", onDivClick, false);
        div.onmousemove = () => {
          clear = true;
        };
      }
    }
  }
}

function onDivClick(e) {
  if (clear) {
    clearDivs();
    clear = false;
  }
  if (e.eventPhase === 2) {
    e.currentTarget.style.backgroundColor = "red";
  }
  const level =
    ["none", "capturing", "target", "bubbling"][e.eventPhase] ?? "error";
  const para = document.createElement("p");
  para.textContent = `${e.currentTarget.id}; eventPhase: ${level}`;
  divInfo.appendChild(para);
}

function clearDivs() {
  for (let i = 0; i < divs.length; i++) {
    if (divs[i].id !== "divInfo") {
      divs[i].style.backgroundColor = i % 2 !== 0 ? "#f6eedb" : "#cceeff";
    }
  }
  divInfo.textContent = "";
}
```

### 結果

仕様書
---

| Specification |
| --- |
| DOM Standard # ref-for-dom-event-eventphase③ |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


PerformanceObserver: PerformanceObserver() コンストラクター - Web API

PerformanceObserver: PerformanceObserver() コンストラクター
===================================================

**`PerformanceObserver()`** コンストラクターは、新しい `PerformanceObserver` オブジェクトを、指定されたオブザーバー `callback` を使用して作成します。オブザーバーコールバックは、パフォーマンス項目イベントが登録された項目型に対して記録されたときに、`observe()` メソッドを介して呼び出されます。

構文
--

```js
new PerformanceObserver(callback)
```

### 引数

`callback`

監視対象のパフォーマンスイベントが記録されたときに呼び出される `PerformanceObserverCallback` コールバック。コールバックが呼び出されるとき、以下の引数が利用できます。

`entries`

パフォーマンスオブザーバー項目のリストです。

`observer`

上記の項目を受け取っている `observer` オブジェクトです。

`droppedEntriesCount` 省略可

バッファーが一杯になったためにバッファーから失われた項目の数です。`buffered` フラグを参照してください。

### 返値

監視対象のパフォーマンスイベントが発生したときに指定されたコールバック (`callback`) を呼び出す新しい `PerformanceObserver` オブジェクト。

例
-

### PerformanceObserver の作成

 次の例では、 "mark" (`PerformanceMark`) および "measure" (`PerformanceMeasure`) イベントを監視する `PerformanceObserver` を作成します。
 `perfObserver` コールバックは `list` (`PerformanceObserverEntryList`) を提供し、監視しているパフォーマンス項目を取得することができます。

```js
function perfObserver(list, observer) {
  list.getEntries().forEach((entry) => {
    if (entry.entryType === "mark") {
      console.log(`${entry.name}'s startTime: ${entry.startTime}`);
    }
    if (entry.entryType === "measure") {
      console.log(`${entry.name}'s duration: ${entry.duration}`);
    }
  });
}
const observer = new PerformanceObserver(perfObserver);
observer.observe({ entryTypes: ["measure", "mark"] });
```

### 失われたバッファー項目

`PerformanceObserver` に `buffered` フラグを使用して、過去のパフォーマンス項目を使用することができます。
 ただし、バッファーサイズには制限があります。パフォーマンスオブザーバーのコールバックにはオプションで `droppedEntriesCount` 引数が格納され、バッファーストレージが一杯になったために失われた項目の数を通知します。

```js
function perfObserver(list, observer, droppedEntriesCount) {
  list.getEntries().forEach((entry) => {
    // do something with the entries
  });
  if (droppedEntriesCount > 0) {
    console.warn(
      `${droppedEntriesCount} entries got dropped due to the buffer being full.`,
    );
  }
}
const observer = new PerformanceObserver(perfObserver);
observer.observe({ type: "resource", buffered: true });
```

通常、リソースタイミング項目はたくさんあり、これらの項目については、 `performance.setResourceTimingBufferSize()` を使用してより大きなバッファを設定し、 `resourcetimingbufferfull` イベントを監視することもできます。

仕様書
---

| Specification |
| --- |
| Performance Timeline # dom-performanceobserver-constructor |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


PerformanceObserver: observe() メソッド - Web API

PerformanceObserver: observe() メソッド
===================================

**`observe()`** は **`PerformanceObserver`** インターフェイスのメソッドで、観測するパフォーマンス項目型のセットを指定します。

項目型の一覧には `PerformanceEntry.entryType` を、ユーザーエージェントが対応している項目型の一覧には `PerformanceObserver.supportedEntryTypes` を使用してください。

一致するパフォーマンス項目が記録されると、パフォーマンスオブザーバーのコールバック関数 (`PerformanceObserver`) の作成時に設定されたコールバック関数が呼び出されます。

構文
--

```js
observe(options)
```

### 引数

`options`

以下の使用可能メンバーを持つオブジェクトです。

`buffered`

論理値のフラグで、バッファリングされた項目をオブザーバーのバッファにキューイングするかどうかを示します。 "`type`" オプションと一緒の場合のみ使用してください。

`durationThreshold`

`PerformanceEventTiming` (en-US) 項目の閾値を定義する `DOMHighResTimeStamp` です。既定値では 104ms で、8ms 単位で丸められます。使用可能な閾値の最小値は 16ms です。 `entryTypes` オプションと一緒に使用することはできません。

`entryTypes`

文字列オブジェクトの配列で、それぞれ観測するパフォーマンス項目の型を指定します。 "`type`", "`buffered`", "`durationThreshold`" オプションと一緒に使用することはできません。

有効なパフォーマンス項目名の一覧は `PerformanceEntry.entryType` を参照ください。認識できない型は無視されますが、開発者がコードをデバッグするのを支援するために、ブラウザーがコンソールに警告メッセージを出力することがあります。有効な型が見つからなかった場合、 `observe()` は何の効果もありません。

`type`

観測するパフォーマンス項目の型を指定する単一の文字列。 `entryTypes` オプションと一緒に使用してはいけません。

### 返値

なし (`undefined`)。

例
-

この例では、2 つの `PerformanceObservers` を作成して設定します。1 つは`"mark"` と `"frame"` イベントを観測し、もう 1 つは `"measure"` イベントを観測します。

```js
const observer = new PerformanceObserver((list, obj) => {
  list.getEntries().forEach((entry) => {
    // Process "mark" and "measure" events
  });
});
observer.observe({ entryTypes: ["mark", "measure"] });
```

### 単一のパフォーマンス項目型を観測

次の例は、`buffered` と `type` の構成オプションを使用して、リソースタイミングイベント (`PerformanceResourceTiming`) のバッファーイベントを取得し、新しいイベントを購読します。オブザーバーが `buffered` または `durationThreshold` オプションを使用するように構成する必要がある場合は、 `entryType` の代わりに `type` を使用します。そうしないと、複数の型のパフォーマンス項目をうまく収集できません。

```js
const observer = new PerformanceObserver((list, obj) => {
  list.getEntries().forEach((entry) => {
    // Process "resource" events
  });
});
observer.observe({ type: "resource", buffered: true });
```

仕様書
---

| Specification |
| --- |
| Performance Timeline # dom-performanceobserver-observe |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


PerformanceObserver: supportedEntryTypes 静的プロパティ - Web API

PerformanceObserver: supportedEntryTypes 静的プロパティ
================================================

**`supportedEntryTypes`** は `PerformanceObserver` インターフェイスの静的読み取り専用プロパティで、このユーザーエージェントが対応している `entryType` 値の配列を返します。

対応している項目のリストはブラウザーごとに異なり、進化しているため、このプロパティによってウェブ開発者は利用できる項目を調べることができます。

値
-

`PerformanceEntry.entryType` 値の配列です。

例
-

### コンソールを使用して対応している値をチェック

ブラウザーの対応している `entryType` 値を探すには、 `PerformanceObserver.supportedEntryTypes` とコンソールに入力します。これは対応している値の配列を返します。

```js
PerformanceObserver.supportedEntryTypes;

// Chrome 99 では ["element", "event", "first-input", "largest-contentful-paint", "layout-shift", "longtask", "mark", "measure", "navigation", "paint", "resource"] を返す
```

### 未対応の型のチェック

以下の関数は、使用可能な項目型の配列に対応しているか調べます。サポートされていない型はコンソールにログ出力されますが、この情報をクライアント側の分析にログ出力して、具体的な型が監視できなかったことを示すこともできます。

```js
function detectSupport(entryTypes) {
  for (const entryType of entryTypes) {
    if (!PerformanceObserver.supportedEntryTypes.includes(entryType)) {
      console.log(entryType);
    }
  }
}

detectSupport(["resource", "mark", "first-input", "largest-contentful-paint"]);
```

仕様書
---

| Specification |
| --- |
| Performance Timeline # supportedentrytypes-attribute |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


PerformanceObserver: takeRecords() メソッド - Web API

PerformanceObserver: takeRecords() メソッド
=======================================

**`takeRecords()`** は `PerformanceObserver` インターフェイスのメソッドで、パフォーマンスオブザーバーに格納されている`パフォーマンス項目`の現在のリストを空にして返します。

構文
--

```js
takeRecords()
```

### 引数

なし。

### 返値

`PerformanceEntry` オブジェクトのリストです。

例
-

### 記録を取る

次の例は、現在のパフォーマンス項目のリストを `records` に格納し、パフォーマンスオブザーバーを空にします。

```js
const observer = new PerformanceObserver((list, obj) => {
  list.getEntries().forEach((entry) => {
    // Process "mark" and "measure" events
  });
});
observer.observe({ entryTypes: ["mark", "measure"] });
const records = observer.takeRecords();
console.log(records[0].name);
console.log(records[0].startTime);
console.log(records[0].duration);
```

仕様書
---

| Specification |
| --- |
| Performance Timeline # dom-performanceobserver-takerecords |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


PerformanceObserver: disconnect() メソッド - Web API

PerformanceObserver: disconnect() メソッド
======================================

**`disconnect()`** は `PerformanceObserver` インターフェイスのメソッドで、パフォーマンスオブザーバーがパフォーマンス項目イベントを受け取らないようにするために使用されます。

構文
--

```js
disconnect()
```

### 引数

なし。

### 返値

なし (`undefined`)。

例
-

### パフォーマンスオブザーバーの停止

次の例では、パフォーマンスオブザーバーを切断して、パフォーマンス項目イベントの受信を無効にしています。

```js
const observer = new PerformanceObserver((list, obj) => {
  list.getEntries().forEach((entry) => {
    // "measure" イベントを処理
    // …
    // それ以降のパフォーマンスイベントを無効化
    observer.disconnect();
  });
});
observer.observe({ entryTypes: ["mark", "measure"] });
```

仕様書
---

| Specification |
| --- |
| Performance Timeline # dom-performanceobserver-disconnect |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


DOMImplementation: createDocument() メソッド - Web API

DOMImplementation: createDocument() メソッド
========================================

**`DOMImplementation.createDocument()`** メソッドは、 `XMLDocument` を作成して返します。

構文
--

```js
createDocument(namespaceURI, qualifiedNameStr)
createDocument(namespaceURI, qualifiedNameStr, documentType)
```

### 引数

`namespaceURI`

作成する文書の名前空間 URI を格納した文字列です。文書が名前空間に属さない場合は `null` です。

`qualifiedNameStr`

作成する文書の修飾名（オプションで接頭辞とコロンにローカルルート要素名を加えたもの）を格納した文字列です。

`documentType` 省略可

作成する文書の `DocumentType` です。既定値は `null` です。

### 返値

なし (`undefined`)。

例
-

```js
const doc = document.implementation.createDocument(
  "http://www.w3.org/1999/xhtml",
  "html",
  null,
);
const body = document.createElementNS("http://www.w3.org/1999/xhtml", "body");
body.setAttribute("id", "abc");
doc.documentElement.appendChild(body);
alert(doc.getElementById("abc")); // [object HTMLBodyElement]
```

仕様書
---

| Specification |
| --- |
| DOM Standard # ref-for-dom-domimplementation-createdocument② |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

関連情報
----

* 所属先の `DOMImplementation` インターフェイス


DOMImplementation: hasFeature() メソッド - Web API

DOMImplementation: hasFeature() メソッド
====================================

**非推奨:** この機能は非推奨になりました。まだ対応しているブラウザーがあるかもしれませんが、すでに関連するウェブ標準から削除されているか、削除の手続き中であるか、互換性のためだけに残されている可能性があります。使用を避け、できれば既存のコードは更新してください。このページの下部にある互換性一覧表を見て判断してください。この機能は突然動作しなくなる可能性があることに注意してください。

**`DOMImplementation.hasFeature()`** メソッドは、指定された機能に対応しているかどうかを示す論理値を返します。これは非推奨です。現代のブラウザーはすべて `true` を返します。

 どのような機能を報告するかは、実装にばらつきがありました。
 最新版の仕様では、このメソッドは機能が正確で使用できる場合は、常に `true` を返すように決定されました。

構文
--

```js
hasFeature(feature, version)
```

### 引数

`feature`

機能名を表す文字列です。

`version`

機能を定義する仕様のバージョンを表す文字列です。

### 返値

なし (`undefined`)。

仕様書
---

| Specification |
| --- |
| DOM Standard # dom-domimplementation-hasfeature |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

関連情報
----

* 所属先の `DOMImplementation` インターフェイス


DOMImplementation: createHTMLDocument() メソッド - Web API

DOMImplementation: createHTMLDocument() メソッド
============================================

**`DOMImplementation.createHTMLDocument()`** メソッドは、新しい HTML 文書 (`Document`) を作成します。

構文
--

```js
createHTMLDocument()
createHTMLDocument(title)
```

### 引数

`title` 省略可

新しい HTML 文書に与えるタイトルを含む文字列です。

### 返値

新しい HTML の `Document` オブジェクトです。

例
-

この例では、新しい HTML 文書を作成し、現在の文書内の `<iframe>` に挿入しています。

この例の HTML は次の通りです。

```html
<body>
  <p>
    Click <a href="javascript:makeDocument()">here</a> to create a new document
    and insert it below.
  </p>
  <iframe id="theFrame" src="about:blank" />
</body>
```

JavaScript による `makeDocument()` は次の通りです。

```js
function makeDocument() {
  let frame = document.getElementById("theFrame");

  let doc = document.implementation.createHTMLDocument("New Document");
  let p = doc.createElement("p");
  p.textContent = "This is a new paragraph.";

  try {
    doc.body.appendChild(p);
  } catch (e) {
    console.log(e);
  }

  // Copy the new HTML document into the frame

  let destDocument = frame.contentDocument;
  let srcNode = doc.documentElement;
  let newNode = destDocument.importNode(srcNode, true);

  destDocument.replaceChild(newNode, destDocument.documentElement);
}
```

4～12 行目のコードは、新しい HTML 文書を作成し、その文書へのコンテンツの挿入を処理するものです。4 行目で `createHTMLDocument()` を用いて、`<title>` が `"New Document"` である新しい HTML 文書を作成しています。5 行目と 6 行目で単純なコンテンツを持つ新しい段落要素を作成し、8～12 行目で新しい段落を新しい文書に挿入する処理をしています。

16 行目はフレームの `contentDocument` を取り出しています。これは新しいコンテンツを注入する文書内のものです。次の 2 行は、新しい文書のコンテンツを新しい文書のコンテキストにインポートする処理です。最後に、20 行目で実際にフレームのコンテンツを新しい文書のコンテンツに置き換えます。

ライブサンプルを見る

返される文書は、以下の HTML であらかじめ構成されたものになります。

```html
<!doctype html>
<html lang="en-US">
  <head>
    <meta charset="UTF-8" />
    <title>title</title>
  </head>
  <body>
    …
  </body>
</html>
```

仕様書
---

| Specification |
| --- |
| DOM Standard # ref-for-dom-domimplementation-createhtmldocument① |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

関連情報
----

* 所属先の `DOMImplementation` インターフェイス


DOMImplementation: createDocumentType() メソッド - Web API

DOMImplementation: createDocumentType() メソッド
============================================

**`DOMImplementation.createDocumentType()`** メソッドは `DocumentType` オブジェクトを返します。これは文書作成時に `DOMImplementation.createDocument` で使用したり、`Node.insertBefore()` や `Node.replaceChild()` などのメソッドで文書中に置いたりすることができます。

構文
--

```js
createDocumentType(qualifiedNameStr, publicId, systemId)
```

### 引数

`qualifiedNameStr`

修飾名の入った文字列です。例えば `svg:svg` です。

`publicId`

`PUBLIC` 識別子の入った文字列です。

`systemId`

`SYSTEM` 識別子の入った文字列です。

### 返値

`DocumentType` です。

例
-

```js
const dt = document.implementation.createDocumentType(
  "svg:svg",
  "-//W3C//DTD SVG 1.1//EN",
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd",
);
const d = document.implementation.createDocument(
  "http://www.w3.org/2000/svg",
  "svg:svg",
  dt,
);
alert(d.doctype.publicId); // -//W3C//DTD SVG 1.1//EN
```

仕様書
---

| Specification |
| --- |
| DOM Standard # ref-for-dom-domimplementation-createdocumenttype① |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

関連情報
----

* 所属先の `DOMImplementation` インターフェイス


AudioSinkInfo: type プロパティ - Web API

AudioSinkInfo: type プロパティ
=========================

**Experimental:** **これは実験的な機能です。**
本番で使用する前にブラウザー互換性一覧表をチェックしてください。

`AudioSinkInfo` インターフェイスの読み取り専用プロパティ **`type`** は、この音声出力デバイスの種類を返します。

値
-

文字列です。現在の値は `none` のみです。

仕様書
---

| Specification |
| --- |
| Web Audio API # dom-audiosinkinfo-type |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

関連情報
----

* SetSinkId test example
* `AudioContext.setSinkId()`
* `AudioContext.sinkId`
* `sinkchange`


ウェブアプリケーションからのファイルの使用 - Web API

ウェブアプリケーションからのファイルの使用
=====================

ファイル API を使用すると、ウェブコンテンツがユーザーにローカルファイルを選択するように指示し、それらのファイルを読み取ることができるようになりました。この選択は HTML の `<input type="file">` 要素を使用したり、ドラッグ & ドロップを行ったりすることで行うことができます。

選択されたファイルへのアクセス
---------------

この HTML を考えてください。

```html
<input type="file" id="input" multiple />
```

ファイル API により、ユーザーが選択したファイルを表す `File` オブジェクトを含む `FileList` にアクセスすることができます。

`multiple` 属性を `input` 要素に付けることで、ユーザーが複数のファイルを選択することができるようになります。

旧来の DOM セレクターを使って、最初に選択されたファイルにアクセスします。

```js
const selectedFile = document.getElementById("input").files[0];
```

### change イベントでの選択されたファイルへのアクセス

`change` イベントを通して `FileList` にアクセスすることもできます (ただし必須ではありません)。このように `EventTarget.addEventListener()` を使って `change` イベントのリスナーを追加する必要があります。

```js
const inputElement = document.getElementById("input");
inputElement.addEventListener("change", handleFiles, false);
function handleFiles() {
  const fileList = this.files; /\* ファイルリストを処理するコードがここに入る \*/
}
```

選択されたファイルについての情報の取得
-------------------

DOM が提供する `FileList` オブジェクトは、`File` オブジェクトとして指定された、ユーザーが選択したすべてのファイルをリストアップします。ファイルリストの `length` 属性の値をチェックすることで、ユーザーが選択したファイルの数を知ることができます。

```js
const numFiles = fileList.length;
```

個々の `File` オブジェクトは、単に配列としてリストにアクセスするだけで取得できます。

```js
for (let i = 0, numFiles = fileList.length; i < numFiles; i++) {
  const file = fileList[i];
  // …
}
```

このループは、ファイルリスト内のすべてのファイルを繰り返し処理します。

`File` オブジェクトには 3 つのプロパティがあり、ファイルに関する有益な情報を得られます。

`name`

読み取り専用の文字列としてのファイル名。これはファイル名のみで、パスに関する情報は含まれていません。

`size`

読み取り専用の 64 ビット整数によるバイト単位のファイルサイズです。

`type`

読み取り専用の文字列としてのファイルの MIME タイプです。MIME タイプが特定できないときは空文字列 (`""`) となります。

### 例: ファイルサイズを表示

次のコードは `size` プロパティを利用する例です。

```html
<!doctype html>
<html lang="ja-JP">
  <head>
    <meta charset="UTF-8" />
    <title>ファイルのサイズ</title>
  </head>

  <body>
    <form name="uploadForm">
      <div>
        <input id="uploadInput" type="file" multiple />
        <label for="fileNum">選択されたファイル:</label>
        <output id="fileNum">0</output>;
        <label for="fileSize">合計サイズ:</label>
        <output id="fileSize">0</output>
      </div>
      <div><input type="submit" value="Send file" /></div>
    </form>

    <script>
 const uploadInput = document.getElementById("uploadInput");
 uploadInput.addEventListener(
 "change",
 () => {
 // 合計サイズを計算
 let numberOfBytes = 0;
 for (const file of uploadInput.files) {
 numberOfBytes += file.size;
 }

 // 最も近い接頭辞単位に近似
 const units = [
 "B",
 "KiB",
 "MiB",
 "GiB",
 "TiB",
 "PiB",
 "EiB",
 "ZiB",
 "YiB",
 ];
 const exponent = Math.min(
 Math.floor(Math.log(numberOfBytes) / Math.log(1024)),
 units.length - 1,
 );
 const approx = numberOfBytes / 1024 \*\* exponent;
 const output =
 exponent === 0
 ? `${numberOfBytes} bytes`
 : `${approx.toFixed(3)} ${
 units[exponent]
 } (${numberOfBytes} bytes)`;

 document.getElementById("fileNum").textContent =
 uploadInput.files.length;
 document.getElementById("fileSize").textContent = output;
 },
 false,
 );
 </script>
  </body>
</html>
```

click() メソッドを使用して非表示の input 要素を使用する
-----------------------------------

見た目の悪い `<input>` 要素を非表示にし、独自のインターフェイスでファイル選択を開き、ユーザーが選択したファイルを表示することができます。 input 要素のスタイルを `display:none` とし、その上で `click()` メソッドを `<input>` に対して呼び出すことで実現できます。

次のような HTML を考えてみましょう。

```html
<input
 type="file"
 id="fileElem"
 multiple
 accept="image/\*"
 style="display:none" />
<button id="fileSelect" type="button">
  いくつかのファイルを選択してください。
</button>
```

`click` イベントを扱うコードは次のようなものです。

```js
const fileSelect = document.getElementById("fileSelect");
const fileElem = document.getElementById("fileElem");

fileSelect.addEventListener(
  "click",
  (e) => {
    if (fileElem) {
      fileElem.click();
    }
  },
  false,
);
```

`<button>` は、好きなようにスタイル付けできます。

label 要素を使用して非表示の file input 要素を起動
----------------------------------

JavaScript (click() メソッド) を使用せずにファイル選択を開けるようにするために、 `<label>` 要素を使用します。この場合、 input 要素に `display: none` (または `visibility: hidden`) を設定して非表示に設定すると、ラベルがキーボードからアクセスできなくなります。代わりに、視覚的に非表示にする手法 (visually-hidden technique) を使用します。

次の HTML を見てください。

```html
<input
 type="file"
 id="fileElem"
 multiple
 accept="image/\*"
 class="visually-hidden" />
<label for="fileElem">いくつかのファイルを選択してください。</label>
```

そしてこの CSS です。

```css
.visually-hidden {
  position: absolute !important;
  height: 1px;
  width: 1px;
  overflow: hidden;
  clip: rect(1px, 1px, 1px, 1px);
}

input.visually-hidden:is(:focus, :focus-within) + label {
  outline: thin dotted;
}
```

JavaScript コードを追加して `fileElem.click()` を呼び出す必要はありません。またこの場合は、ラベル要素のスタイルを希望どおりに設定することもできます。前例のようにアウトラインに設定したり、background-color や box-shadow を設定したりして、ラベルの非表示入力フィールドのフォーカスステータスを視覚的に示す必要があります。(この記事を書いている時点では、 Firefox は `<input type="file">` 要素に対してこの視覚的な手がかりを表示していません。)

ドラッグ & ドロップを使用したファイルの選択
-----------------------

ユーザーがファイルをウェブアプリケーションにドラッグ & ドロップすることもできます。

最初のステップは、ドロップゾーンを確立することです。コンテンツのどの部分がドロップを受け入れるかは、アプリケーションの設計によって異なりますが、要素がドロップイベントを受け取れるようにするのは簡単です。

```js
let dropbox;

dropbox = document.getElementById("dropbox");
dropbox.addEventListener("dragenter", dragenter, false);
dropbox.addEventListener("dragover", dragover, false);
dropbox.addEventListener("drop", drop, false);
```

この例では、ID `dropbox` を持つ要素をドロップゾーンに指定しています。これは、`dragenter`、`dragover`、`drop` の各イベントのリスナーを追加することで行われます。

実際には、この場合、 `dragenter` と `dragover` のイベントでは何もする必要はありませんので、これらの関数はどちらも簡単です。これらの関数はイベントの伝播を停止し、既定のアクションが発生しないようにするだけです。

```js
function dragenter(e) {
  e.stopPropagation();
  e.preventDefault();
}

function dragover(e) {
  e.stopPropagation();
  e.preventDefault();
}
```

本当の魔法は `drop()` 関数の中で起こります。

```js
function drop(e) {
  e.stopPropagation();
  e.preventDefault();

  const dt = e.dataTransfer;
  const files = dt.files;

  handleFiles(files);
}
```

ここでは、イベントから `dataTransfer` フィールドを取得し、そこからファイルリストを取得し、それを `handleFiles()` に渡します。これより先は、ユーザーが入力要素を使用したかドラッグ & ドロップを使用するかどうかにかかわらず、ファイルの処理方法は全く同じです。

例: ユーザーが選択した画像のサムネイルを表示
-----------------------

次の素晴らしい写真共有サイトを開発していて、ユーザーが実際に画像をアップロードする前に HTML を使って画像のサムネイルプレビューを表示させたいとしましょう。前に説明したように `input` 要素やドロップゾーンを設定し、次の `handleFiles()` のような関数を呼び出せば良いのです。

```js
function handleFiles(files) {
  for (let i = 0; i < files.length; i++) {
    const file = files[i];

    if (!file.type.startsWith("image/")) {
      continue;
    }

    const img = document.createElement("img");
    img.classList.add("obj");
    img.file = file;
    preview.appendChild(img); // 「プレビュー」とは、コンテンツが表示される div 出力のことを想定しています。

    const reader = new FileReader();
    reader.onload = (e) => {
      img.src = e.target.result;
    };
    reader.readAsDataURL(file);
  }
}
```

ここでは、ユーザーが選択したファイルを処理するループが各ファイルの `type` 属性を見て、その MIME タイプが "`image/`" という文字列で始まるかどうかを確認しています。画像である各ファイルに対して、新しい `img` 要素を作成します。CSS は、きれいな境界線や影を設定したり、画像のサイズを指定したりするために使用しますので、ここでは必要ありません。

各画像には CSS クラス `obj` が追加されており、DOM ツリーで簡単に見つけることができます。また、各画像に `file` 属性を追加し、画像の `File` を指定しています。これにより、後で実際にアップロードする画像を取得することができます。`Node.appendChild()` を使用して、文書のプレビュー領域に新しいサムネイルを追加します。

次に、画像の読み込みと `img` 要素へのアタッチを非同期で処理するための `FileReader` を確立します。新しい `FileReader` オブジェクトを作成した後、その `onload` 関数を設定し、`readAsDataURL()` を呼び出してバックグラウンドで読み込み処理を開始します。画像ファイルのコンテンツ全体が読み込まれると、それらは `data:` URL に変換され、`onload` コールバックに渡されます。このルーチンの実装では、`img` 要素の `src` 属性が読み込まれた画像に設定され、その結果、画像がユーザの画面のサムネイルに表示されます。

オブジェクト URL を利用する
----------------

DOM の `URL.createObjectURL()` と `URL.revokeObjectURL()` メソッドを使用すると、ユーザーのコンピューター上のローカルファイルなど、DOM `File` オブジェクトを使用して参照可能なあらゆるデータを参照するために使用できるシンプルな URL 文字列を作成できます。

HTML から URL で参照したい `File` オブジェクトがある場合は、次のようにオブジェクト URL を作成します。

```js
const objectURL = window.URL.createObjectURL(fileObj);
```

オブジェクト URL は `File` オブジェクトを識別する文字列です。 `URL.createObjectURL()` を呼び出すたびに、すでにそのファイルのオブジェクト URL を作成していても、一意のオブジェクト URL が作成されます。これらはそれぞれ解除する必要があります。これらはドキュメントがアンロードされると自動的に解放されますが、ページが動的にこれらを使用している場合は `URL.revokeObjectURL()` を呼び出して明示的に解放する必要があります。

```js
URL.revokeObjectURL(objectURL);
```

例: オブジェクト URL で画像を表示
--------------------

この例では、オブジェクト URL を使用して画像のサムネイルを表示しています。さらに、ファイル名やサイズなどの他のファイル情報も表示します。

インターフェースとなる HTML は次のようになります。

```html
<input
 type="file"
 id="fileElem"
 multiple
 accept="image/\*"
 style="display:none" />
<a href="#" id="fileSelect">いくつかのファイルを選択してください。</a>
<div id="fileList">
  <p>ファイルが選択されていません。</p>
</div>
```

これにより、ファイル `<input>` 要素と、ファイル選択を呼び出すリンクが確立されます (あまり美しくないファイル入力を非表示にするため)。これは、ファイル選択を呼び出すメソッドと同様に、click() メソッドを使用して非表示の input 要素を使用するの節で説明されています。

`handleFiles()` メソッドは次のようになります。

```js
const fileSelect = document.getElementById("fileSelect"),
  fileElem = document.getElementById("fileElem"),
  fileList = document.getElementById("fileList");

fileSelect.addEventListener(
  "click",
  (e) => {
    if (fileElem) {
      fileElem.click();
    }
    e.preventDefault(); // "#" への移動を防ぐ
  },
  false,
);

fileElem.addEventListener("change", handleFiles, false);

function handleFiles() {
  if (!this.files.length) {
    fileList.innerHTML = "<p>ファイルが選択されていません。</p>";
  } else {
    fileList.innerHTML = "";
    const list = document.createElement("ul");
    fileList.appendChild(list);
    for (let i = 0; i < this.files.length; i++) {
      const li = document.createElement("li");
      list.appendChild(li);

      const img = document.createElement("img");
      img.src = URL.createObjectURL(this.files[i]);
      img.height = 60;
      img.onload = () => {
        URL.revokeObjectURL(img.src);
      };
      li.appendChild(img);
      const info = document.createElement("span");
      info.innerHTML = `${this.files[i].name}: ${this.files[i].size} バイト`;
      li.appendChild(info);
    }
  }
}
```

これは、 `<div>` の URL を `fileList` という ID で取得することから始まります。これは、サムネイルを含むファイルリストを挿入するブロックです。

`handleFiles()` に渡された `FileList` オブジェクトが `null` の場合、ブロックの内部 HTML に「ファイルが選択されていません」と表示するように設定します。そうでない場合は、次のようにファイルリストの構築を開始します。

1. 新しく順序なしリスト (`<ul>`) 要素を作成します。
2. 新しいリスト要素は、`<div>` ブロックの中に `Node.appendChild()` メソッドを呼び出すことで挿入されます。
3. `files` で表される `FileList` 内のそれぞれの `File` に対して次の処理を実行します。
    1. 新しくリスト項目 (`<li>`) 要素を作成し、リストに挿入します。
    2. 新しく画像 (`<img>`) 要素を作成します。
    3. `URL.createObjectURL()` を用いて、Blob の URL を作成して、画像のソースをファイルを表す新しいオブジェクト URL に設定します。
    4. 画像の高さを 60 ピクセルに設定します。
    5. 画像が読み込まれると不要になるため、画像の読み込みイベントハンドラーを設定してオブジェクトの URL を解放します。これは `URL.revokeObjectURL()` メソッドを呼び出し、`img.src` で指定したオブジェクト URL 文字列を渡すことで行います。
    6. 新しいリスト項目をリストに追加する。

上のコードのライブデモはこちらです。

例: ユーザが選択したファイルを送信
------------------

もう１つは、ユーザーが選択したファイルやファイル (先ほどの例で選択した画像など) をサーバーにアップロードできるようにすることです。これは非常に簡単に非同期で行うことができます。

### アップロードタスクの生成

前の例でサムネイルを作成したコードの続きで、すべてのサムネイル画像が CSS クラス `obj` にあり、対応する `File` が `file` 属性に添付されていることを思い出してください。これにより、このように`Document.querySelectorAll()`を使用して、ユーザーがアップロードするために選択した画像をすべて選択することができます。

```js
function sendFiles() {
  const imgs = document.querySelectorAll(".obj");

  for (let i = 0; i < imgs.length; i++) {
    new FileUpload(imgs[i], imgs[i].file);
  }
}
```

2 行目は、CSS クラス `obj` を持つドキュメント内のすべての要素の `NodeList` を取得し `imgs` と呼ばれる変数に格納します。この例では、これらの要素はすべての画像サムネイルになります。このリストを取得したら、それを参照して、それぞれの新しい `FileUpload` インスタンスを作成するのは簡単です。それぞれが対応するファイルのアップロードを処理します。

### ファイルのアップロード処理を行う

`FileUpload` 関数は 2 つの入力、画像要素と画像データを読み込むファイルを受け付けます。

```js
function FileUpload(img, file) {
  const reader = new FileReader();
  this.ctrl = createThrobber(img);
  const xhr = new XMLHttpRequest();
  this.xhr = xhr;

  const self = this;
  this.xhr.upload.addEventListener(
    "progress",
    (e) => {
      if (e.lengthComputable) {
        const percentage = Math.round((e.loaded \* 100) / e.total);
        self.ctrl.update(percentage);
      }
    },
    false,
  );

  xhr.upload.addEventListener(
    "load",
    (e) => {
      self.ctrl.update(100);
      const canvas = self.ctrl.ctx.canvas;
      canvas.parentNode.removeChild(canvas);
    },
    false,
  );
  xhr.open(
    "POST",
    "http://demos.hacks.mozilla.org/paul/demos/resources/webservices/devnull.php",
  );
  xhr.overrideMimeType("text/plain; charset=x-user-defined-binary");
  reader.onload = (evt) => {
    xhr.send(evt.target.result);
  };
  reader.readAsBinaryString(file);
}

function createThrobber(img) {
  const throbberWidth = 64;
  const throbberHeight = 6;
  const throbber = document.createElement("canvas");
  throbber.classList.add("upload-progress");
  throbber.setAttribute("width", throbberWidth);
  throbber.setAttribute("height", throbberHeight);
  img.parentNode.appendChild(throbber);
  throbber.ctx = throbber.getContext("2d");
  throbber.ctx.fillStyle = "orange";
  throbber.update = (percent) => {
    throbber.ctx.fillRect(
      0,
      0,
      (throbberWidth \* percent) / 100,
      throbberHeight,
    );
    if (percent === 100) {
      throbber.ctx.fillStyle = "green";
    }
  };
  throbber.update(0);
  return throbber;
}
```

上の `FileUpload()` 関数は、進捗情報を表示するための throbber を作成し、データのアップロードを処理するための `XMLHttpRequest` を作成します。

実際にデータを転送する前に、いくつかの準備段階があります。

1. `XMLHttpRequest` のアップロード `progress` リスナーは、アップロードの進捗に応じて最新の情報に基づいて throbber が更新されるように、新しいパーセント値の情報で throbber を更新するように設定されています。
2. `XMLHttpRequest` のアップロード `load` イベントハンドラーは、進捗インジケーターが実際に 100 % に達することを確認するために、throbber の進捗情報を 100% に更新するように設定されています (プロセス中に粒度のクセがある場合)。そして、必要がなくなれば throbber を削除します。これにより、アップロードが完了すると throbber が消えます。
3. 画像ファイルをアップロードするリクエストは、 `XMLHttpRequest` の `open()` メソッドを呼び出して POST リクエストを生成することで開始されます。
4. アップロードの MIME タイプは `XMLHttpRequest` 関数の `overrideMimeType()` を呼び出して設定します。この場合、一般的な MIME タイプを使用しています。用途によっては MIME タイプを設定する必要がない場合もあります。
5. `FileReader` オブジェクトを使用して、ファイルをバイナリー文字列に変換します
6. 最後に、コンテンツがロードされると、 `XMLHttpRequest` 関数の `send()` が呼び出され、ファイルのコンテンツがアップロードされます。
### ファイルのアップロード処理を非同期に扱う

この例では、サーバー側で PHP を使用し、クライアント側で JavaScript を使用して、ファイルの非同期アップロードを実演しています。

```php
<?php
if (isset($\_FILES['myFile'])) {
 // 例:
 move\_uploaded\_file($\_FILES['myFile']['tmp\_name'], "uploads/" . $\_FILES['myFile']['name']);
 exit;
}
?><!DOCTYPE html>
<html lang="ja-JP">
<head>
  <meta charset="UTF-8">
  <title>dnd binary upload</title>
    <script type="application/javascript">
 function sendFile(file) {
 const uri = "/index.php";
 const xhr = new XMLHttpRequest();
 const fd = new FormData();

 xhr.open("POST", uri, true);
 xhr.onreadystatechange = () => {
 if (xhr.readyState === 4 && xhr.status === 200) {
 alert(xhr.responseText); // handle response.
 }
 };
 fd.append('myFile', file);
 // multipart/form-data のアップロードを開始します。
 xhr.send(fd);
 }

 window.onload = () => {
 const dropzone = document.getElementById("dropzone");
 dropzone.ondragover = dropzone.ondragenter = (event) => {
 event.stopPropagation();
 event.preventDefault();
 }

 dropzone.ondrop = (event) => {
 event.stopPropagation();
 event.preventDefault();

 const filesArray = event.dataTransfer.files;
 for (let i=0; i<filesArray.length; i++) {
 sendFile(filesArray[i]);
 }
 }
 }
 </script>
</head>
<body>
    <div>
        <div id="dropzone" style="margin:30px; width:500px; height:300px; border:1px dotted grey;">ここにファイルをドラッグ & ドロップしてください</div>
    </div>
</body>
</html>
```

例: オブジェクト URL を使用して PDF を表示
---------------------------

オブジェクト URL は画像以外にも使用できます。埋め込まれた PDF ファイルや、ブラウザーで表示可能な他のリソースを表示するために使用できます。

Firefox では、 PDF が iframe 内に埋め込まれて表示されるようにするには (ダウンロードファイルとして提案されるのではなく)、`pdfjs.disabled` の設定を `false`
Non-standard
 に設定する必要があります。

```html
<iframe id="viewer"></iframe>
```

そして、`src` 属性の変更点はこちらです。

```js
const obj_url = URL.createObjectURL(blob);
const iframe = document.getElementById("viewer");
iframe.setAttribute("src", obj_url);
URL.revokeObjectURL(obj_url);
```

例: 他のファイル形式でのオブジェクト URL の使用
---------------------------

他の形式のファイルも同じように操作できます。ここでは、アップロードされた動画をプレビューする方法を紹介します。

```js
const video = document.getElementById("video");
const obj_url = URL.createObjectURL(blob);
video.src = obj_url;
video.play();
URL.revokeObjectURL(obj_url);
```

関連情報
----

* `File`
* `FileList`
* `FileReader`
* `URL`
* `XMLHttpRequest`
* XMLHttpRequest の使用


SubtleCrypto の暗号以外の使用法 - Web API

SubtleCrypto の暗号以外の使用法
======================

 この記事では、SubtleCrypto インターフェイスの `digest` メソッドの使い道に焦点を当てます。Web Crypto API に含まれる他の多くのメソッドの用途は暗号関係のかなり限られたものですが、データのハッシュを求めること (これが `digest` メソッドが行うことです) には多くの便利な利用法があります。

この記事では、SubtleCrypto インターフェイスの暗号関係の使い道は扱いません。この記事から学ぶべき重要なことは、強力で低レベルなので、製品での暗号関係の目的には **この API を使ってはいけない** ということです。正しく使うためには、暗号関係のタスクを正しく成し遂げるために多くの状況依存の手順を踏まなければならないでしょう。もしこれらの手順のうち 1 個でも間違って行われると、よくてあなたのコードは動かず、より悪い場合にはそれは *動き* 、知らないうちに安全でない製品でユーザーを危険に晒すことになるでしょう。

Web Crypto API を使う必要はまったくないかもしれません。暗号を使いたくなるであろう目的の多くは、既に解決され、ウェブプラットフォームの一部になっています。例えば、クライアントとサーバーの間で情報を読んでいる Wi-Fi ホットスポットのような中間者攻撃が心配なのであれば、HTTPS を確実に正しく使うことで解決できます。ユーザー間で情報を安全に送信したいですか？それなら、標準の一部として暗号化することになっている WebRTC Data Channels (en-US) を用いてユーザー間のデータ接続を構築できます。

SubtleCrypto インターフェイスは暗号を扱うための低レベルのプリミティブを提供しますが、それらの道具を用いてシステムを実装することは複雑なタスクです。間違いに気付くのは難しく、結果としてユーザーのデータがあなたが考えるより安全でなくなる可能性があります。このことにより、ユーザーがセンシティブなデータや重要なデータを共有している場合、悲惨な結果が生じる可能性があります。

疑問がある場合は、自分でやろうとせず、経験者を雇い、ソフトウェアがセキュリティの専門家によって確実に監査されるようにしてください。

ファイルのハッシュ化
----------

これは、Web Crypto API を用いてできる最も単純で役立つものです。鍵や証明書の生成は不要で、1 個だけの手順でできます。

ハッシュ化は、大きなバイト列を小さい文字列に変換し、この長い列の中の小さな変更が小さい文字列の大きな変化を生む技術です。この技術は、それぞれのファイルの全バイトをチェックせずに 2 個の同一のファイルを特定するのに便利です。これは、比較対象として単純な文字列が手に入るので、非常に便利です。明確にしておくと、ハッシュ化は **一方向の** 操作です。ハッシュからもとのバイト列を生成することはできません。

生成された 2 個のハッシュが同じだが、それらを生成するのに用いたファイルが違う場合は、*ハッシュ衝突* として知られます。これは偶然起こる可能性は非常に小さく、SHA256 のような安全なハッシュ関数では、人工的に起こすこともほぼ不可能です。そのため、2 個の文字列が同じ場合は、2 個のもとのファイルも同一であると合理的に確信することができます。

現時点では ファイルのハッシュ化には通常 SHA256 を用いますが、SubtleCrypto インターフェイスではより次数が高いハッシュ関数も利用可能です。最もよく使われる SHA256 ハッシュの表現は、64 個の十六進数字の列です。十六進というのは、0-9 および a-f の文字のみを用い、4 ビットの情報を表すということです。すなわち、簡単に言うと、SHA256 ハッシュは任意の長さのデータをほぼ一意な 256 ビットのデータに変換します。

この技術は、ダウンロードしたファイルが作者が意図したものと一致することを確認するために、実行可能ファイルをダウンロードできるサイトでよく用いられます。これにより、ユーザーがマルウェアをインストールしていないことを保証できます。このための最もよく使われる方法は、以下の通りです。

1. ウェブサイトが提供するファイル名と SHA256 チェックサムを書き留めます。
2. 実行可能ファイルをダウンロードします。
3. 端末で `sha256sum /path/to/the/file` を実行し、自分自身で文字列を生成します。Mac を使っている場合は、別にインストールする必要があるかもしれません。
4. 2 個の文字列を比較します。ファイルが壊れていなければ、一致するはずです。

![ソフトウェア「Blender」のダウンロードにおける SHA256 の例。64 個の十六進数字に続いて、「blender.zip」のようなファイル名があります。](/ja/docs/Web/API/Web_Crypto_API/Non-cryptographic_uses_of_subtle_crypto/blender-sha256-example.png)

SubtleCrypto の `digest()` メソッドは、このために便利です。ファイルのチェックサムの生成は、以下のようにできます。

まず、ファイルを読み込み、出力される SHA-256 を表示するための HTML 要素を用意します。

```html
<h3>ファイルを SHA256 でハッシュ化するデモ</h3>

<label
 >ハッシュ化するファイルを選択 (複数可)
  <input type="file" id="file" name="file" multiple
/></label>
<output style="display:block;font-family:monospace;"></output>
```

次に、SubtleCrypto インターフェイスを用いて処理します。以下のように動作します。

* FileReader を用い、ファイルを ArrayBuffer に読み込みます。
* `crypto.subtle.digest('SHA-256', arrayBuffer)` を用いて `ArrayBuffer` のダイジェストを求めます。
* 結果のハッシュ (別の `ArrayBuffer`) を表示できるように文字列に変換します。

```js
const output = document.querySelector("output");
const file = document.getElementById("file");

// ユーザーが 1 個以上のファイルを選択した時、ハッシュ化関数を実行する
file.addEventListener("change", hashTheseFiles);

// digest 関数は非同期であり、Promise を返す
// コードを単純にするため、async/await 構文を用いる
async function fileHash(file) {
  const arrayBuffer = await file.arrayBuffer();

  // subtle crypto API を用い、ファイルが入った ArrayBuffer の SHA256 を求める
  // 結果のハッシュは ArrayBuffer に格納される
  const hashAsArrayBuffer = await crypto.subtle.digest("SHA-256", arrayBuffer);

  // 文字列として表示するため、ArrayBuffer の各バイトの十六進表現を求める
  // まず、ArrayBuffer の各バイトそれぞれを要素とする配列を作成する
  const uint8ViewOfHash = new Uint8Array(hashAsArrayBuffer);
  // 次に、各要素を十六進文字列に変換するため、通常の配列に変換する
  // 0-9 または a-f の各文字が 0 と 16 の間の数値を表し、4 ビットの情報を保持するので、2 文字で 8 ビット (1 バイト) を表す
  const hashAsString = Array.from(uint8ViewOfHash)
    .map((b) => b.toString(16).padStart(2, "0"))
    .join("");
  return hashAsString;
}

async function hashTheseFiles(e) {
  let outHTML = "";
  // ファイル選択欄の各ファイルについて処理を行う
  for (const file of this.files) {
    // ハッシュを求め、出力要素に並べる
    outHTML += `${file.name} ${await fileHash(file)}`;
  }
  output.innerHTML = outHTML;
}
```

### どのような場面で使えるか？

この時点で、「*これを自分のウェブサイトで使って、ユーザーがファイルをダウンロードするとき、ハッシュが一致することを保証し、ユーザーに自分のダウンロードが安全であると安心させることができる*」と自分で考えているかもしれません。残念ながら、ここにはすぐに頭に浮かぶ 2 個の懸念点があります。

* 実行可能ファイルのダウンロードは **常に** HTTPS で行われるべきです。これにより中間者は攻撃できなくなるため、冗長かもしれません。
* 攻撃者がもとのサーバー上のダウンロードファイルを置き換えることができる場合、SubtleCrypto インターフェイスを呼び出すコードも単に置き換え、バイパスし、全部大丈夫ですとだけ表示するようにすることもできるでしょう。自分のコードで見つけるのは難しいような厳密な等価性比較の置き換えなど、こっそりと行われる可能性が高いです。

```diff
--- if (checksum === correctCheckSum) return true;
+++ if (checksum = correctCheckSum) return true;
```

価値がある可能性がある場面の一つは、自分の制御下にないサードパーティのダウンロード元から取得したファイルを検査したい場合です。これは、ファイルをユーザーに提供する前にスキャンできるようにする CORS ヘッダがダウンロード元で有効になっている場合は成立します。残念ながら、CORS がデフォルトで有効になっているサーバーは多くありません。

「ハッシュにソルトを加える」とは？
-----------------

「*ハッシュにソルトを加える*」という言葉を聞いたことがあるかもしれません。ここで扱っているトピックと直接は関係ないですが、知っておくのはいいでしょう。

**メモ:** この節ではパスワードのセキュリティを扱っていますが、SubtleCrypto が提供するハッシュ関数はこの用途には適しません。この用途には、`scrypt` や `bcrypt` などの高コストで遅いハッシュ関数が必要です。SHA は非常に速く高効率になるよう設計されているので、パスワードのハッシュ化には適しません。この節は純粋な興味のためのものです。Web Crypto API をクライアントでパスワードをハッシュ化するために用いてはいけません。

ハッシュ化がよく使われるのはパスワードです。ユーザーのパスワードを平文で保存したいことは決してないでしょう。それは単純にひどい考えです。かわりにユーザーのパスワードのハッシュを保存することで、ハッカーがユーザー名とパスワードのデータベースを入手してももとのパスワードを復元できないようにします。細かいことに気がつく人は、既知のパスワードのリストから生成したハッシュを入手したパスワードのハッシュのリストと比較することで、もとのパスワードを入手できるということに気付くかもしれません。パスワードに文字列を連結すると、ハッシュが変わり、一致しなくなります。これは **ソルト** として知られています。もう一つの厄介な問題は、それぞれのパスワードで同じソルトを用いると、同じハッシュに対応するパスワードは同じもとのパスワードになってしまうことです。このため、1 個のパスワードが分かると、一致するすべてのパスワードがわかってしまいます。

この問題を解決するため、*ハッシュにソルトを加える* として知られる操作を行います。それぞれのパスワードに対し、ソルト (ランダムな文字列) を生成し、パスワードの文字列と連結します。そして、ハッシュとソルトを同じデータベースに保存し、ユーザーが後にログインしようとしたとき一致するかを確認できるようにします。これにより、2 人のユーザーが同じパスワードを用いても、ハッシュは異なるものになります。ここで、高コストな暗号学的関数が必要な理由は、よく使われるパスワードのリストを用いてもとのパスワードを求めるのに時間がかかりすぎるようにするためです。

SHA を用いたハッシュテーブル
----------------

暗号学的に安全ではないハッシュを高速で生成するために、SHA1 を用いることができます。これは、任意のデータを後で検索するためのキーに変換するのに非常に便利です。

例えば、行のフィールドの一つとして大きなデータを含むデータベースを持ちたいとします。すると、フィールドの一つを可変長またはあり得る最大の大きさのデータを保存できる大きさにする必要があるため、データベースの効率が悪くなります。かわりの解決法の一つは、データのハッシュを生成し、ハッシュをインデックスとする別のルックアップテーブルにデータを保存することです。すると、もとのデータベースにはハッシュを保存するだけでよくなり、これは都合のいい固定長です。

SHA1 ハッシュのあり得る種類は非常に多いです。そのため、たまたま同じ SHA1 ハッシュを持つ 2 種類のデータを生成することはほとんど不可能です。SHA1 は暗号学的に安全ではないので、同じ SHA1 ハッシュを持つ 2 種類のファイルをわざと生成することは *可能* です。そのため、理論上、悪意のあるユーザーはハッシュが同じため検出されずにデータベース内のもとのデータを置き換えるデータを生成できます。これは考慮する価値がある攻撃ベクトルです。

Git がファイルを保存する方法
----------------

Git は、SHA1 ハッシュを 2 通りの興味深い使い方をする、素晴らしい例です。ファイルが Git に保存されるときは、SHA1 ハッシュによって参照されます。これにより、Git がデータを素早く探し、ファイルを取り出せるようになります。

ただし、単にファイルの内容をハッシュに使っているわけではなく、UTF8 の文字列 `"blob "`、十進数で現したバイト単位のファイルサイズ、ナル文字 (JavaScript では `"\0"` と書ける) をこの順で前につけます。JavaScript の文字列は UTF16 なので、Encoding API の TextEncoder インターフェイス を用いて UTF8 の文字列をエンコードできます。

以下のコードは、SHA256 の例と同様に、ファイルからこれらのハッシュを求めるのに用いることができます。ファイルをアップロードするための HTML は同じですが、Git が行うのと同様のサイズ情報を前につける処理を追加しています。

```html
<h3>Git がファイルに SHA1 をどのように使っているかのデモ</h3>

<label
 >ハッシュ化するファイルを選択 (複数可)
  <input type="file" id="file" name="file" multiple
/></label>

<output style="display:block;font-family:monospace;"></output>
```

```js
const output = document.querySelector("output");
const file = document.getElementById("file");
file.addEventListener("change", hashTheseFiles);

async function fileHash(file) {
  const arrayBuffer = await file.arrayBuffer();

  // Git はナル終端の文字列 'blob 1234' (1234 はファイルサイズを表す)
  // をハッシュ化前に前置するので、これを再現する

  // まず、ファイルのバイト単位のサイズを求める
  const uint8View = new Uint8Array(arrayBuffer);
  const length = uint8View.length;

  // git は端末では文字列に UTF8 を用いるが、ウェブでは UTF16 を用いる
  // メッセージ中の文字のバイナリ表現が違うとハッシュも変わるので、エンコーダーを使う必要がある
  const encoder = new TextEncoder();
  // ナル終端とは、文字列がナル文字 (JavaScript では '\0') で終わるということ
  const view = encoder.encode(`blob ${length}\0`);

  // そして、2 個の ArrayBuffer を合体して 1 個の ArrayBuffer にする
  const newBlob = new Blob([view.buffer, arrayBuffer], {
    type: "text/plain",
  });
  const arrayBufferToHash = await newBlob.arrayBuffer();

  // 最後に、ハッシュ化する。今回は Git が用いる SHA1 を用いる
  // そして、表示用の文字列として返す
  return hashToString(await crypto.subtle.digest("SHA-1", arrayBufferToHash));
}

function hashToString(arrayBuffer) {
  const uint8View = new Uint8Array(arrayBuffer);
  return Array.from(uint8View)
    .map((b) => b.toString(16).padStart(2, "0"))
    .join("");
}

// 前回と同様、各ファイルについて処理を行う
async function hashTheseFiles(e) {
  let outHTML = "";
  for (const file of this.files) {
    outHTML += `${file.name} ${await fileHash(file)}`;
  }
  output.innerHTML = outHTML;
}
```

もとの ArrayBuffer に連結してハッシュ化する文字列を生成するためのヘッダを生成するために Encoding API を使っている方法に注目しましょう。

Git がコミットハッシュを生成する方法
--------------------

興味深いことに、Git は複数の情報に基づく似たやり方でコミットハッシュを生成します。ここには以前のコミットハッシュやコミットメッセージを含むことができ、これらも新しいハッシュを生成するもととなります。これは、いくつかの一意な識別子に基づくコミットを参照するのに用いることができます。

端末で用いるコマンド: `(printf "commit %s\0" $(git --no-replace-objects cat-file commit HEAD | wc -c); git cat-file commit HEAD) | sha1sum`

出典: How is git commit sha1 formed

本質的には、以下の UTF8 文字列です。(ナル文字は `\0` で表現されています)
```

commit [size in bytes as decimal of this info]\0tree [tree hash]
parent [parent commit hash]
author [author info] [timestamp]
committer [committer info] [timestamp]

commit message
```

これは素晴らしいことです。なぜなら、個別のフィールドで一意であることを保証できるものは無いですが、組み合わせると単一のコミットを指す一意なポインターになるからです。しかし、この文字列全体は長すぎて扱いにくいです。そこで、ハッシュ化することにより、複数のフィールドから短くて共有しやすい新しい一意な文字列を得ることができます。

これが、メッセージを全く変えずにコミットを amend してもハッシュが変わる理由です。コミットのタイムスタンプが変わり、1 文字変わっただけでも新しいハッシュを完全に変えるのには十分です。

ここで学ぶべきことは、データのキーを設定したいがどの単一の情報も十分一意にならないとき、複数の文字列を連結してハッシュ化するのが有用なキーを生成するための素晴らしい方法だということです。

これらの例が、この新しい強力な API に注目するきっかけになれば幸いです。暗号関係のものを自分で再現しようとしてはいけないということは覚えておいてください。道具があり、その中には `crypto.digest()` 関数などの日々の開発に有用な道具もあるということを覚えておけば十分です。


DataTransfer.setDragImage() - Web API

DataTransfer.setDragImage()
===========================

ドラッグが発生すると、ドラッグ対象（`dragstart` イベントが発生した要素）から半透明の画像が生成され、ドラッグ中にマウスポインターに沿って移動します。この画像は自動的に作成されるので、自分で作成する必要はありません。ただし、カスタム画像が必要な場合は、**`DataTransfer.setDragImage()`** メソッドを使用して、使用するカスタム画像を設定することができます。画像は通常、 `<image>` 要素になりますが、 `<canvas>` やその他の可視要素であっても構いません。

メソッドの `x` 座標と `y` 座標は、マウスポインターに対する画像の相対的な表示方法を定義します。これらの座標は、マウスカーソルがあるべき画像のオフセットを定義します。例えば、ポインターが中心に来るように画像を表示するには、画像の幅と高さの半分の値を使用します。

このメソッドは `dragstart` イベントハンドラー内で呼び出す必要があります。

構文
--

```js
setDragImage(imgElement, xOffset, yOffset);
```

### 引数

`imgElement`

ドラッグのフィードバック画像に使用する画像 `Element` 要素です。

もし `Element` が img 要素であれば、ドラッグデータストアのビットマップを （その要素に固有のサイズで）その要素の画像に設定します。そうでなければ、ドラッグデータストアのビットマップを、与えられた要素から生成された画像に設定します（そのための正確なメカニズムは現在のところ指定されていません）。

注: もし `Element` が既存の `HTMLElement` であれば、ドラッグフィードバック画像として表示するために、ビューポートに表示されている必要があります。あるいは、この目的のために、画面外にあるような新しい DOM 要素を作成することができます。

`xOffset`

`long` で、画像内の水平方向のオフセットを示します。

`yOffset`

`long` で、画像内の垂直方向のオフセットを示します。

### 返値

なし (`undefined`)。

例
-

この例では、`setDragImage()` メソッドの使用方法を示します。この例では `example.gif` という名前の画像ファイルを参照していることに注意しましょう。そのファイルが存在する場合はそのファイルがドラッグ画像として使用され、そのファイルが存在しない場合はブラウザーが既定のドラッグ画像を使用します。

デモ

```js
<!DOCTYPE html>
<html lang=en>
<title>Example of DataTransfer.setDragImage()</title>
<meta name="viewport" content="width=device-width">
<style>
  div {
    margin: 0em;
    padding: 2em;
  }
  #source {
    color: blue;
    border: 1px solid black;
  }
  #target {
    border: 1px solid black;
  }
</style>
<script>
function dragstart\_handler(ev) {
 console.log("dragStart");
 // ドラッグのフォーマットとデータを設定します。データにはイベントターゲットの ID を使用します。
 ev.dataTransfer.setData("text/plain", ev.target.id);
 // 画像を作成してドラッグ画像に使用する
 // 注意: "example.gif" を既存の画像に変更しないと画像が作成されず、
 // デフォルトのドラッグ画像が使用されます。
 const img = new Image();
 img.src = 'example.gif';
 ev.dataTransfer.setDragImage(img, 10, 10);
}

function dragover\_handler(ev) {
 console.log("dragOver");
 ev.preventDefault();
}

function drop\_handler(ev) {
 console.log("Drop");
 ev.preventDefault();
 // ドロップ対象のIDであるデータを取得します。
 const data = ev.dataTransfer.getData("text");
 ev.target.appendChild(document.getElementById(data));
}
</script>
<body>
<h1>Example of <code>DataTransfer.setDragImage()</code></h1>
 <div>
   <p id="source" ondragstart="dragstart\_handler(event);" draggable="true">
     この要素を選択し、ドロップゾーンにドラッグしてから放すと要素が移動します。</p>
 </div>
 <div id="target" ondrop="drop\_handler(event);" ondragover="dragover\_handler(event);">ドロップゾーン</div>
</body>
</html>
```

仕様書
---

| Specification |
| --- |
| HTML Standard # dom-datatransfer-setdragimage-dev |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

関連情報
----

* ドラッグ＆ドロップ
* ドラッグ操作
* 推奨されるドラッグ型
* 複数の項目のドラッグ＆ドロップ
* DataTransfer test - Paste or Drag


DataTransfer.setData() - Web API

DataTransfer.setData()
======================

**`DataTransfer.setData()`** メソッドは、ドラッグ操作の `drag data` に指定したデータと型を設定します。与えられた型のデータが存在しない場合、このデータはドラッグデータストアの末尾に加えられ、このような `types` リストの最後の項目は新しい型になります。与えられた型のデータが存在する場合、既存のデータが同じ位置で置き換えられます。同じ型のデータが置き換えられる時、`types` リストの並び順は変更されません。

データ型は、例えば `text/plain` や `text/uri-list` です。

構文
--

```js
setData(format, data);
```

### 引数

`format`

文字列で、ドラッグオブジェクトに追加するドラッグデータの型を表します。

`data`

文字列で、ドラッグオブジェクトに追加するデータを表します。

### 返値

なし (`undefined`)。

例
-

この例は、`DataTransfer` オブジェクトの `getData()` メソッドおよび `setData()` メソッド、`clearData()` メソッドの使い方を紹介します。

```js
<!DOCTYPE html>
<html lang=en>
<title>Examples of DataTransfer's setData(), getData() and clearData()</title>
<meta content="width=device-width">
<style>
  div {
    margin: 0em;
    padding: 2em;
  }
  #source {
    color: blue;
    border: 1px solid black;
  }
  #target {
    border: 1px solid black;
  }
</style>
<script>
function dragstart\_handler(ev) {
 console.log("dragStart");
 // Change the source element's background color to signify drag has started
 ev.currentTarget.style.border = "dashed";
 // Set the drag's format and data. Use the event target's id for the data
 ev.dataTransfer.setData("text/plain", ev.target.id);
}

function dragover\_handler(ev) {
 console.log("dragOver");
 ev.preventDefault();
}

function drop\_handler(ev) {
 console.log("Drop");
 ev.preventDefault();
 // Get the data, which is the id of the drop target
 const data = ev.dataTransfer.getData("text");
 ev.target.appendChild(document.getElementById(data));
 // Clear the drag data cache (for all formats/types)
 ev.dataTransfer.clearData();
}
</script>
<body>
<h1>Examples of <code>DataTransfer</code>: <code>setData()</code>, <code>getData()</code>, <code>clearData()</code></h1>
 <div>
   <p id="source" ondragstart="dragstart\_handler(event);" draggable="true">
     Select this element, drag it to the Drop Zone and then release the selection to move the element.</p>
 </div>
 <div id="target" ondrop="drop\_handler(event);" ondragover="dragover\_handler(event);">Drop Zone</div>
</body>
</html>
```

仕様書
---

| Specification |
| --- |
| HTML Standard # dom-datatransfer-setdata-dev |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

関連情報
----

* ドラッグ＆ドロップ
* ドラッグ操作
* 推奨されるドラッグ型
* 複数の項目のドラッグ＆ドロップ
* DataTransfer test - Paste or Drag


DataTransfer.files - Web API

DataTransfer.files
==================

**`files`** は `DataTransfer` オブジェクトのプロパティで、ドラッグ操作中のファイルのリストです。操作にファイルが含まれていない場合、リストは空になります。

この機能を利用して、ユーザーのデスクトップからブラウザーにファイルをドラッグすることができます。

**メモ:** `DataTransfer` オブジェクトの `files` プロパティは、 `drop` イベントの中からのみアクセスできます。それ以外のどのイベントでも、 `files` プロパティは空になります。その基礎となるデータストアが保護モードになるからです。

返値
--

ドラッグ操作中のファイルのリストで、 1 つのリスト項目が 1 つのファイルを表します。操作にファイルが含まれていない場合、リストは空になります。

例
-

このインターフェイスには 2 つのライブ例があります。

* Firefox 専用: https://jsfiddle.net/9C2EF/
* すべてのブラウザー: https://jsbin.com/hiqasek/
仕様書
---

| Specification |
| --- |
| HTML Standard # dom-datatransfer-files-dev |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.


DataTransfer.getData() - Web API

DataTransfer.getData()
======================

**`DataTransfer.getData()`** メソッドは、指定した型のドラッグデータを（文字列として）受け取ります。ドラッグ操作がデータを含んでいない場合、このメソッドは空文字列を返します。

データ型は、例えば `text/plain` や `text/uri-list` です。

構文
--

```js
getData(format);
```

引数
--

`format`

文字列で、受け取るデータの型を表します。

### 返値

文字列で、 `format` で指定した型のドラッグデータを表します。ドラッグ操作にデータがなかったり、 `format` で指定した型のデータがなかったりした場合、このメソッドは空文字列を返します。

### 注意事項

* データの利用可能性
    + HTML5 Drag and Drop 仕様書では、「ドラッグデータストアモード」が規定されています。
     これは、 **`DataTransfer.getData()`** が期待した値を返さないという、予期しない動作をする可能性があります。すべてのブラウザーがこの制限を強制しているわけではないからです。
     `dragstart` と `drop` イベントの処理中は、安全にデータにアクセスすることができます。それ以外のイベントでは、データは利用できないものと考えてください。それでも、項目とその形式を列挙することは可能です。
例
-

この例は、`DataTransfer` オブジェクトの `getData()` メソッドおよび `setData()` メソッドの使い方を紹介します。

### HTML コンテンツ

```html
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)">
  <span id="drag" draggable="true" ondragstart="drag(event)"
 >drag me to the other box</span
 >
</div>
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
```

### CSS コンテンツ

```css
#div1,
#div2 {
  width: 100px;
  height: 50px;
  padding: 10px;
  border: 1px solid #aaaaaa;
}
```

### JavaScript

```js
function allowDrop(allowdropevent) {
  allowdropevent.target.style.color = "blue";
  allowdropevent.preventDefault();
}

function drag(dragevent) {
  dragevent.dataTransfer.setData("text", dragevent.target.id);
  dragevent.target.style.color = "green";
}

function drop(dropevent) {
  dropevent.preventDefault();
  const data = dropevent.dataTransfer.getData("text");
  dropevent.target.appendChild(document.getElementById(data));
  document.getElementById("drag").style.color = "black";
}
```

### 結果

仕様書
---

| Specification |
| --- |
| HTML Standard # dom-datatransfer-getdata-dev |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

関連情報
----

* ドラッグ＆ドロップ
* ドラッグ操作
* 推奨されるドラッグ型
* 複数の項目のドラッグ＆ドロップ
* DataTransfer test - Paste or Drag


DataTransfer.dropEffect - Web API

DataTransfer.dropEffect
=======================

**`DataTransfer.dropEffect`** プロパティは、ドラッグ＆ドロップ操作中にユーザーに与えられるフィードバック（通常は視覚的）を制御します。これは、ドラッグ中に表示されるカーソルに影響します。例えば、ユーザーがターゲットのドロップ要素の上にカーソルを置くと、ブラウザーのカーソルが、どの種類の操作が発生するかを示すことができます。

`DataTransfer` オブジェクトを作成すると、 `dropEffect` には文字列の値が設定されます。取得時には、現在の値を返します。設定時、新しい値が以下の値のいずれかであれば、プロパティの現在の値が新しい値に設定され、それ以外の値は無視されます。

`dragenter` および `dragover` イベントでは、ユーザーがどのような操作を要求しているかに基づいて、`dropEffect` が初期化されます。これをどのように決定するかはプラットフォームによって異なりますが、通常、ユーザーは alt キーなどの修飾キーを押して、希望する操作を調整することができます。`dragenter` と `dragover` イベントのイベントハンドラー内では、ユーザーが要求している操作とは異なる操作が必要な場合、`dropEffect` を修正する必要があります。

`drop` および `dragend` イベントでは、 `dropEffect` に希望した動作が設定されます。これは、 `dropEffect` が前回の `dragenter` または `dragover` イベントの後に有していた値となります。例えば `dragend` イベントにおいて、望ましい dropEffect が "move" であれば、ドラッグされたデータをソースから削除する必要があります。

値
-

文字列で、ドラッグ操作の効果を表します。取りうる値は以下の通りです。

`copy`

新しい場所にソースアイテムのコピーが作成されます。

`move`

アイテムを新しい場所に移動します。

`link`

新しい場所のソースにリンクが確立されます。

`none`

アイテムはドロップしない場合があります。

`dropEffect` に他の値を代入しても効果はなく、古い値が保持されます。

例
-

この例では、`dropEffect` と`effectAllowed` プロパティを使用しています。

### HTML

```html
<div>
  <p id="source" ondragstart="dragstart\_handler(event);" draggable="true">
    この要素を選択し、ドロップゾーンにドラッグして放すと、要素が移動します。
  </p>
</div>
<div
 id="target"
 ondrop="drop\_handler(event);"
 ondragover="dragover\_handler(event);">
  ドロップゾーン
</div>
```

### CSS

```css
div {
  margin: 0em;
  padding: 2em;
}

#source {
  color: blue;
  border: 1px solid black;
}

#target {
  border: 1px solid black;
}
```

### JavaScript

```js
function dragstart\_handler(ev) {
  console.log(
    "dragStart: dropEffect = " +
      ev.dataTransfer.dropEffect +
      " ; effectAllowed = " +
      ev.dataTransfer.effectAllowed,
  );

  // この要素の id をドラッグ ペイロードに追加し、ドロップ ハンドラーが
  // どの要素をツリーに追加するかを知ることができるようにします。
  ev.dataTransfer.setData("text", ev.target.id);
  ev.dataTransfer.effectAllowed = "move";
}

function drop\_handler(ev) {
  console.log(
    "drop: dropEffect = " +
      ev.dataTransfer.dropEffect +
      " ; effectAllowed = " +
      ev.dataTransfer.effectAllowed,
  );
  ev.preventDefault();

  // ターゲットの ID を取得し、移動した要素をターゲットの DOM に追加します。
  var data = ev.dataTransfer.getData("text");
  ev.target.appendChild(document.getElementById(data));
}

function dragover\_handler(ev) {
  console.log(
    "dragOver: dropEffect = " +
      ev.dataTransfer.dropEffect +
      " ; effectAllowed = " +
      ev.dataTransfer.effectAllowed,
  );
  ev.preventDefault();
  // dropEffect を移動するように設定します。
  ev.dataTransfer.dropEffect = "move";
}
```

### 結果

仕様書
---

| Specification |
| --- |
| HTML Standard # dom-datatransfer-dropeffect-dev |

ブラウザーの互換性
---------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

関連情報
----

* ドラッグ＆ドロップ
* ドラッグ操作
* 推奨されるドラッグ型
* 複数の項目のドラッグ＆ドロップ
* DataTransfer test - Paste or Drag