FormData オブジェクトの使用 - Web API

FormData オブジェクトの使用
==================

`FormData` オブジェクトは、フェッチまたは XMLHttpRequest API を使用して送信するためのキーと値のペアの集合をコンパイルできます。本来はフォームデータの送信に使用することを想定していましたが、キーのついたデータを伝送するためにフォームとは独立して使用することもできます。伝送されるデータは、フォームのエンコードタイプが `multipart/form-data` に設定されている場合に、`submit()` メソッドで送信する際に使用するデータと同じ形式です。

ゼロから `FormData` オブジェクトを作成する
---------------------------

以下のように `FormData` オブジェクトはあなた自身で作成でき、インスタンス化したら `append()` メソッドを呼び出すことでフィールドに付加します。

```js
const send = document.querySelector("#send");

send.addEventListener("click", async () => {
  const formData = new FormData();
  formData.append("username", "Groucho");
  formData.append("accountnum", 123456);

  // file 型の <input> 要素
  const avatar = document.querySelector("#avatar");
  formData.append("avatar", avatar.files[0]);

  // JavaScript のファイル風オブジェクト
  const content = '<q id="a"><span id="b">hey!</span></q>';
  const blob = new Blob([content], { type: "text/xml" });
  formData.append("webmasterfile", blob);

  const response = await fetch("http://example.org/post", {
    method: "POST",
    body: formData,
  });
  console.log(await response.json());
});
```

**メモ:** `"avatar"` および `"webmasterfile"` フィールドはどちらも、ファイルを含んでいます。フィールド `"accountnum"` に与えた数値は `FormData.append()` メソッドにより直ちに文字列へ変換されます（フィールドの値として `Blob`、 `File`、文字列のいずれかを取ることができます。値が `Blob` でも `File` でもない場合は、文字列に変換されます）。

この例では、 `"username"`, `"accountnum"`, `"avatar"`, `"webmasterfile"` というフィールドの値を含む `FormData` インスタンスを構築し、 `fetch()` を使用してフォームのデータを送信します。 `"webmasterfile"` フィールドは `Blob` です。 `Blob` オブジェクトは、不変的な生データのファイルのようなオブジェクトを表します。 Blob は、必ずしも JavaScript に適した形式ではないデータを表します。 `File` インターフェースは `Blob` をベースにしており、 Blob の機能を継承し、ユーザーのシステム上のファイルをサポートするように拡張されています。 `Blob` を作成するには、 `Blob()` コンストラクターを呼び出します。

HTML フォームから `FormData` オブジェクトを取り出す
----------------------------------

既存の `<form>` のデータを含む `FormData` オブジェクトを構築するには、 `FormData` オブジェクトの作成時にその form 要素を指定します。

**メモ:** `FormData` は `name` 属性を使用する入力フィールドのみを使用します。

```js
const formData = new FormData(someFormElement);
```

例:

```js
const send = document.querySelector("#send");

send.addEventListener("click", async () => {
  // <form> 要素
  const userInfo = document.querySelector("#user-info");
  const formData = new FormData(userInfo);

  const response = await fetch("http://example.org/post", {
    method: "POST",
    body: formData,
  });
  console.log(await response.json());
});
```

以下のように、`FormData` オブジェクトをフォームより取得してから送信するまでの間に、追加のデータを付加することもできます。

```js
const send = document.querySelector("#send");

send.addEventListener("click", async () => {
  const userInfo = document.querySelector("#user-info");
  const formData = new FormData(userInfo);
  formData.append("serialnumber", 12345);

  const response = await fetch("http://example.org/post", {
    method: "POST",
    body: formData,
  });
  console.log(await response.json());
});
```

これにより、必ずしもユーザーが編集可能である必要がない追加情報を含めるために、送信前にフォームデータを拡張することができます。

FormData オブジェクトを使用したファイルの送信
---------------------------

`FormData` を使用してファイルを送信することもできます。type が "file" である `<input>` 要素を、`<form>` に含めます。

```html
<form enctype="multipart/form-data" method="post" name="fileinfo" id="fileinfo">
  <p>
    <label
 >Your email address:
      <input
 type="email"
 autocomplete="on"
 name="userid"
 placeholder="email"
 required
 size="32"
 maxlength="64" />
    </label>
  </p>
  <p>
    <label
 >Custom file label:
      <input type="text" name="filelabel" size="12" maxlength="32" />
    </label>
  </p>
  <p>
    <label
 >File to stash:
      <input type="file" name="file" required />
    </label>
  </p>
  <p>
    <input type="submit" value="Stash the file!" />
  </p>
</form>
```

そして、以下のようなコードを使用して送信できます。

```js
const form = document.querySelector("#fileinfo");

form.addEventListener("submit", async (event) => {
  const formData = new FormData(form);

  formData.append("CustomField", "This is some extra data");

  const response = await fetch("stash.php", {
    method: "POST",
    body: formData,
  });
  event.preventDefault();
});
```

**メモ:** フォームへの参照を渡した場合は、 `open()` の呼び出しで指定したリクエストメソッドよりもフォームで指定したメソッドを優先します。

**警告:** FormData を使用して、`XMLHttpRequest` またはフェッチ API を使用して、 `multipart/form-data` の Content-Type で POST リクエストを送信する場合（ファイルや Blob をサーバーにアップロードする場合など）、リクエストの `Content-Type` ヘッダーを明示的に設定しないでください。そうすると、ブラウザーがリクエスト本文のフォームフィールドの区切りに使用する境界の表現で Content-Type ヘッダーを設定することができなくなります。

以下のように、直接 `File` や `Blob` を `FormData` オブジェクトへ追加することもできます。

```js
data.append("myfile", myBlob, "filename.txt");
```

`append()` メソッドを使用する際は、オプションの第 3 引数を使用して、`Content-Disposition` ヘッダーに含めるファイル名を渡すことができます。これはサーバーへ送信されます。ファイル名を指定しない（あるいは引数がサポートされない）場合は、 "blob" という名前が使用されます。

formdata イベントの使用
----------------

`FormData` オブジェクトよりも新しくプラットフォームに追加されたのが `formdata` イベントです。これは、フォームのデータを表すエントリーのリストが作成された後に `HTMLFormElement` オブジェクトで発行されます。このイベントは、フォームが送信されたときに発行されますが、 `FormData()` コンストラクターが呼び出されたときにも発行されます。

これにより、 `FormData` オブジェクトを `formdata` イベントの発行を受けてすばやく取得することができるようになり、自分でまとめる必要がなくなります。

例えば、 JavaScript では次のようにフォームを参照できます。

```js
const formElem = document.querySelector("form");
```

`submit` イベントのハンドラーでは、 `preventDefault` を使用して既定のフォーム送信を停止してから、 `FormData` コンストラクターを呼び出して `formdata` イベントを発行させます。

```js
formElem.addEventListener("submit", (e) => {
  // フォーム送信時に既定の動作を抑止
  e.preventDefault();

  // FormData オブジェクトを作成し、 formdata イベントを発行
  new FormData(formElem);
});
```

`formdata` イベントが発行されると、 `FormData` オブジェクトに `FormDataEvent.formData` を使ってアクセスし、必要な処理を行うことができます（以下では、 `XMLHttpRequest` を使ってサーバーに送信しています）。

```js
formElem.addEventListener("formdata", (e) => {
  console.log("formdata fired");

  // イベントオブジェクトから形式データを取得します。
  const data = e.formData;
  for (const value of data.values()) {
    console.log(value);
  }

  // fetch() でデータを送信
  fetch("/formHandler", {
    method: "POST",
    body: data,
  });
});
```

分かりましたか
-------

`FormData` オブジェクトは、無効になっているフィールドや無効になっているフィールドセットのデータを含めることはできません。

関連情報
----

* フェッチ API の使用
* `HTMLFormElement`
* `Blob`
* 型付き配列


XMLHttpRequest における HTML の扱い - Web API

XMLHttpRequest における HTML の扱い
============================

W3C の `XMLHttpRequest` 仕様書では、もともと XML の解釈しか対応していなかった `XMLHttpRequest` に HTML の解釈を追加しています。この機能によって、ウェブアプリは `XMLHttpRequest` を使って HTML を解釈済の DOM として取得することができます。

一般的な `XMLHttpRequest` の使い方についての概要は、 XMLHttpRequest の利用をお読みください。

制限
--

同期的な `XMLHttpRequest` の利用を避けるために、 HTML 対応は同期モードでは利用できません。また、 HTML 対応は `responseType` プロパティが `"document"` に設定されている時にのみ有効です。この制限によって、古いコードが `XMLHttpRequest` を使って `responseText` が `text/html` であるリソースを既定のモードで受け取るときに、無用に HTML を解釈する時間を浪費することを防ぎます。また、この制限によって HTTP のエラーページ (ふつうは `text/html` の応答本文を持つ) の際に `responseXML` が `null` と想定する古いコードで問題が発生することを防ぐこともできます。

使用方法
----

`XMLHttpRequest` を使って HTML リソースを DOM として取得することは、 `XMLHttpRequest` を使って XML リソースを DOM として取得するのと似ていますが、同期モードを使用することはできず、 `XMLHttpRequest` オブジェクトの `open()` を呼び出した後、 `send()` を呼び出す前に、 `responseType` プロパティに文字列 `"document"` 代入して、明示的に文書を要求する必要があるという点が異なります。

```js
const xhr = new XMLHttpRequest();
xhr.onload = () => {
  console.log(xhr.responseXML.title);
};
xhr.open("GET", "file.html");
xhr.responseType = "document";
xhr.send();
```

機能の検出
-----

### 方法 1

この方法は「強制的に非同期」である性質を利用するものです。 `XMLHttpRequest` オブジェクトを同期モードで開いた後、 `responseType` 設定しようとすると、機能を実装しているブラウザーではエラーを投げますが、それ以外のブラウザーではそのまま動作します。

```js
function HTMLinXHR() {
  if (!window.XMLHttpRequest) {
    return false;
  }
  const req = new window.XMLHttpRequest();
  req.open("GET", window.location.href, false);
  try {
    req.responseType = "document";
  } catch (e) {
    return true;
  }
  return false;
}
```

JSFiddle で閲覧

この方法は同期的であり、他の資産に頼りませんが、この機能があることを示すだけで実際の機能をチェックするものではないので、次の方法 2 の方がより信頼できるかもしれません。

### 方法 2

ブラウザーが `XMLHttpRequest` で HTML の解釈処理に対応しているかどうかを確実に検出するには、二つの課題があります。まず、 HTML 対応が非同期モードでしか有効でないことから、検出結果は非同期で受け取られることになります。第二に、 `data:` URL を使用すると同時に `data:` URL の対応にも依存することになるため、実際に HTTP を通じて文書を取得しなければならないことです。

つまり、 HTML 対応を検出するには、サーバ上にテスト用の HTML 文書が必要になります。このテストファイルは小さく、整形式の XML ではないものです。

```html
<title>&&<</title>
```

このファイルが `detect.html` という名前だった場合、 HTML 対応を検出する関数は次のように書くことができます。

```js
function detectHtmlInXhr(callback) {
  if (!window.XMLHttpRequest) {
    setTimeout(function () {
      callback(false);
    }, 0);

    return;
  }
  let done = false;
  const xhr = new window.XMLHttpRequest();
  xhr.onreadystatechange = () => {
    if (xhr.readyState === 4 && !done) {
      done = true;
      callback(
        !!(
          xhr.responseXML &&
          xhr.responseXML.title &&
          xhr.responseXML.title === "&&<"
        ),
      );
    }
  };
  xhr.onabort = xhr.onerror = () => {
    if (!done) {
      done = true;
      callback(false);
    }
  };
  try {
    xhr.open("GET", "detect.html");
    xhr.responseType = "document";
    xhr.send();
  } catch (e) {
    setTimeout(function () {
      if (!done) {
        done = true;
        callback(false);
      }
    }, 0);
  }
}
```

引数の `callback` は非同期に呼び出される関数であり、 HTML 対応がある場合には唯一の引数が `true` になり、 HTML 対応がない場合は唯一の引数が `false` になります。

JSFiddle で閲覧

文字エンコーディング
----------

HTTP の `Content-Type` ヘッダーで文字エンコーディングが宣言されている場合は、そのエンコーディングが使用されます。そうでない場合、もしバイトオーダーマークがある場合は、そのバイトオーダーマークが示すエンコーディングを使用します。そうでない場合、もしファイルの先頭 1024 バイト以内にエンコーディングを宣言する `<meta>` 要素がある場合は、そのエンコーディングが使用されます。それもない場合、ファイルは UTF-8 としてデコードされます。

仕様書
---

| Specification |
| --- |
| XMLHttpRequest Standard # interface-xmlhttprequest |

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

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

関連情報
----

* `XMLHttpRequest`
* XMLHttpRequest の使用


バイナリーデータの送信と受信 - Web API

バイナリーデータの送信と受信
==============

XMLHttpRequest オブジェクトの `responseType` プロパティで、サーバーに期待する応答の種類を変更することができます。設定可能な値は空文字列 (既定), `"arraybuffer"`, `"blob"`, `"document"`, `"json"`, `"text"` です。 `response` プロパティにはエンティティの本体が `responseType` に応じて `ArrayBuffer`, `Blob`, `Document`, `JSON` または文字列で格納されます。要求が不完全であったり成功しなかった場合は `null` になります。

このサンプルでは画像をバイナリーファイルとして読み込み、生のバイト列から 8 ビット符号なし整数値の配列を作成します。なお、これは画像をデコードしてピクセルを読み取ることは行いません。そのためには png デコードライブラリーが必要になるでしょう。

```js
const req = new XMLHttpRequest();
req.open("GET", "/myfile.png", true);
req.responseType = "arraybuffer";

req.onload = (event) => {
  const arrayBuffer = req.response; // Note: not req.responseText
  if (arrayBuffer) {
    const byteArray = new Uint8Array(arrayBuffer);
    byteArray.forEach((element, index) => {
      // do something with each byte in the array
    });
  }
};

req.send(null);
```

`responseType` プロパティに `"blob"` という文字列を設定すると、バイナリーファイルを `Blob` として読み取ることもできます。

```js
const req = new XMLHttpRequest();
req.open("GET", "/myfile.png", true);
req.responseType = "blob";

req.onload = (event) => {
  const blob = req.response;
  // ...
};

req.send();
```

古いブラウザーでのバイナリーデータの受信
--------------------

下に示す `loadBinaryResource()` 関数は、指定した URL からロードしたバイナリーデータを関数の呼び元に返します。

```js
function loadBinaryResource(url) {
  const req = new XMLHttpRequest();
  req.open("GET", url, false);

  // XHR binary charset opt by Marcus Granado 2006 [http://mgran.blogspot.com]
  req.overrideMimeType("text/plain; charset=x-user-defined");
  req.send(null);
  return req.status === 200 ? req.responseText : "";
}
```

マジックは 5 行目で、 MIME タイプを上書きしてブラウザーに強制的に、ユーザー定義の文字セットを使用したプレインテキストとして扱わせます。これにより、ブラウザーはこれを解釈せず、未処理のままバイト列を通します。

```js
const filestream = loadBinaryResource(url);
const abyte = filestream.charCodeAt(x) & 0xff; // throw away high-order byte (f7)
```

上記のサンプルでは、ロードしたバイナリーデータ内のオフセット `x` のバイトを取得します。 `x` の有効範囲は 0 から `filestream.length-1` です。

詳細な説明は downloading binary streams with XMLHttpRequest を見て下さい。

バイナリーデータの送信
-----------

XMLHttpRequest の `send` メソッドが拡張され、 `ArrayBuffer`、`Blob`、`File` オブジェクトを受け付けることでバイナリーデータの送信が容易になりました.

続くサンプルはその場で作ったテキストファイルを `POST` メソッドで "file" をサーバーに送信します。このサンプルはプレインテキストを使っていますが、代わりにデータがバイナリーファイルだとイメージする事も出来ます。

```js
const req = new XMLHttpRequest();
req.open("POST", url, true);
req.onload = (event) => {
  // Uploaded
};

const blob = new Blob(["abc123"], { type: "text/plain" });

req.send(blob);
```

バイナリーデータとして型付き配列を送信
-------------------

同等にバイナリーデータとして JavaScript の型付き配列を送信することもできます。

```js
// Create a new array with fake data (Consecutive numbers (0 - 255), looping back to 0)
const array = new Uint8Array(512).map((v, i) => i);

const xhr = new XMLHttpRequest();
xhr.open("POST", url, false);
xhr.send(array);
```

これは 8 ビット整数の 512 バイトの配列を構築して送信します。勿論、好きな任意のバイナリーデータで使えます。

フォーム送信とファイルアップロード
-----------------

`FormData` を参照してください。


同期と非同期のリクエスト - Web API

同期と非同期のリクエスト
============

`XMLHttpRequest` は同期と非同期通信の両方に対応しています。しかし、一般的には性能上の理由により、同期リクエストより非同期リクエストを選択すべきです。

同期リクエストはプログラムの実行をブロックし、画面を「フリーズ」させたりユーザー操作が反応しない状態にしたりすることがあります。

非同期リクエスト
--------

非同期 `XMLHttpRequest` を使用すると、データが到着したときにコールバックを受け取ります。これにより、リクエストが処理されている間、ブラウザーは通常通りに動作することができます。

### 例: コンソールログへファイルを送信する

最も簡単な非同期 `XMLHttpRequest` の使用法を示します。

```js
const xhr = new XMLHttpRequest();
xhr.open("GET", "/bar/foo.txt", true);
xhr.onload = (e) => {
  if (xhr.readyState === 4) {
    if (xhr.status === 200) {
      console.log(xhr.responseText);
    } else {
      console.error(xhr.statusText);
    }
  }
};
xhr.onerror = (e) => {
  console.error(xhr.statusText);
};
xhr.send(null);
```

2 行目で第 3 引数を `true` にすることで、リクエストを非同期に処理することを指定しています。

3 行目はイベントハンドラー関数オブジェクトを生成し、リクエストの `onload` 属性に割り当てています。このハンドラーは、4 行目でリクエストの `readyState` を見てトランザクションが完了したかどうかを確認し、もしそうであり、かつ HTTP ステータスが 200 であれば、受信した内容をコンソールにダンプします。エラー発生時には、エラーメッセージが表示されます。

15 行目では実際にリクエストを開始します。コールバック処理は状態が変化するたびに呼び出されます。

### 例: 外部ファイルを読込む標準的な関数を書く

たくさんの外部ファイルを読み込まなければならないことがあります。これは `XMLHttpRequest` オブジェクトを非同期で使用して、読み込まれたファイルの内容を指定されたリスナに切り替える標準的な関数です。

```js
function xhrSuccess() {
  this.callback.apply(this, this.arguments);
}

function xhrError() {
  console.error(this.statusText);
}

function loadFile(url, callback, ...args) {
  const xhr = new XMLHttpRequest();
  xhr.callback = callback;
  xhr.arguments = args;
  xhr.onload = xhrSuccess;
  xhr.onerror = xhrError;
  xhr.open("GET", url, true);
  xhr.send(null);
}
```

使用法は次の通りです。

```js
function showMessage(message) {
  console.log(`${message} ${this.responseText}`);
}

loadFile("message.txt", showMessage, "New message!\n\n");
```

ユーティリティ関数 ***loadFile*** の引数は、 (i) (HTTP の GET リクエストを介して) 読み込む対象の URL、 (ii) XHR 操作の正常終了時に実行する関数、 (iii) 任意で XHR オブジェクトから成功時のコールバック関数に (`arguments` プロパティで) そのまま渡される追加の引数のリストです。

1 行目では、 XHR 操作の正常終了時に呼び出される関数を宣言しています。これは、 loadFile 関数の呼び出しの中で XHR オブジェクトのプロパティに (11 行目で) 割り当てられたコールバック関数 (この場合は `showMessage` 関数) を呼び出します。 `loadFile` 関数の呼び出しに提供される追加の引数は (もしあれば)、コールバック関数の実行時に「適用」されます。

5 行目では、 XHR 操作の完了に失敗した時に呼び出される関数を宣言しています。

11 行目では、 `loadFile` の第 2 引数で渡された成功時のコールバック関数を XHR オブジェクトの `callback` プロパティに格納します。

12 行目では、 `loadFile` の呼び出しで与えられた引数の配列を分割します。第 3 引数以降、残りのすべての引数が集められ、変数 `xhr` の arguments プロパティに割り当てられ、成功時のコールバック関数 `xhrSuccess` に渡され、最終的には `xhrSuccess` 関数から呼び出されるコールバック関数 (この場合は `showMessage` 関数) に渡されます。

15 行目では、リクエストを非同期に処理することを指示するため、第 3 引数に `true` を指定しています．

16 行目で実際にリクエストを実行しています。

### 例: タイムアウトの利用

読み込みが行われるのを待つ間、プログラムが永遠に待つことを防ぐためにタイムアウトを利用することができます。これは次のように、 `XMLHttpRequest` オブジェクト上の `timeout` プロパティの値を設定することで行うことができます。

```js
function loadFile(url, timeout, callback, ...args) {
  const xhr = new XMLHttpRequest();
  xhr.ontimeout = () => {
    console.error(`The request for ${url} timed out.`);
  };
  xhr.onload = () => {
    if (xhr.readyState === 4) {
      if (xhr.status === 200) {
        callback.apply(xhr, args);
      } else {
        console.error(xhr.statusText);
      }
    }
  };
  xhr.open("GET", url, true);
  xhr.timeout = timeout;
  xhr.send(null);
}
```

`ontimeout` ハンドラーを設定することで、 "timeout" イベントを処理するコードを追加していることに注意してください。

使用方法は次の通りです。

```js
function showMessage(message) {
  console.log(`${message} ${this.responseText}`);
}

loadFile("message.txt", 2000, showMessage, "New message!\n");
```

ここではタイムアウトを 2000 ミリ秒に設定しています．

同期リクエスト
-------

**警告:** 同期 XHR リクエストは、特にネットワークの状態が悪かったり、リモートサーバの応答が遅かったりしたときに、しばしばウェブ上でハングアップの原因となります。同期 XHR は非推奨であり、使用しないようにして、代わりに非同期リクエストを使用してください。

`timeout` や `abort` 等の XHR の新機能は同期 XHR では許可されていません。実行すると `InvalidAccessError` が発生するでしょう。

### 例: HTTP 同期リクエスト

この例は単純な同期リクエストの作成方法を示しています。

```js
const request = new XMLHttpRequest();
request.open("GET", "/bar/foo.txt", false); // `false` で同期リクエストになる
request.send(null);

if (request.status === 200) {
  console.log(request.responseText);
}
```

3 行目でリクエストを送信しています。引数が `null` であることは、 `GET` リクエストに本文が必要ないことを示しています。

5 行目ではトランザクション完了後，ステータスコードをチェックしています。結果のコードが 200 — HTTP の "OK" の結果 — ならば、文書のテキストコンテンツがコンソールに出力されます。

### 例: ワーカーからの同期 HTTP リクエスト

同期リクエストが通常、実行をブロックしない稀な例として、 `Worker` 内での `XMLHttpRequest` の利用があります。

**`example.html`** (主ページ):

```html
<!doctype html>
<html lang="en-US">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width" />
    <title>MDN Example</title>
    <script>
 const worker = new Worker("myTask.js");
 worker.onmessage = (event) => {
 alert(`Worker said: ${event.data}`);
 };

 worker.postMessage("Hello");
 </script>
  </head>
  <body>
    …
  </body>
</html>
```

**`myFile.txt`** (`XMLHttpRequest` 同期呼出しの対象):
```

Hello World!!
```

**`myTask.js`** (`Worker`):

```js
self.onmessage = (event) => {
  if (event.data === "Hello") {
    const xhr = new XMLHttpRequest();
    xhr.open("GET", "myFile.txt", false); // 同期リクエスト
    xhr.send(null);
    self.postMessage(xhr.responseText);
  }
};
```

**メモ:** `Worker` を使っているため、結果的には非同期になります。

これは、バックグラウンドでサーバーとやり取りしたり、一部のコンテンツを先読みしたりするために便利です。例と詳細については ウェブワーカーの利用を参照して下さい。

### 同期 XHR を使用する場面をビーコン API で対応する

`XMLHttpRequest` の同期的な使用が置き換えられない場面がいくつかあります。例えば `unload`, `beforeunload`, `pagehide` などのイベントの処理中などです。 `fetch()` API を `keepalive` フラグ付きで使用することを検討してください。 `fetch` API を `keepalive` フラグ付きで使用できないのであれば、ふつうは快適なユーザー操作を提供するために `navigator.sendBeacon()` API でこれらの場合に対応することができます。

次の例は、 unload ハンドラー内で同期 `XMLHttpRequest` を使用してサーバーにデータを送信することを試みる、実験的な分析コードを示しています。この結果、ページのアンロードに遅延が発生します。

```js
window.addEventListener("unload", logData, false);

function logData() {
  const client = new XMLHttpRequest();
  client.open("POST", "/log", false); // 第 3 引数で同期 XHR を指定しています。 :(
  client.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
  client.send(analyticsData);
}
```

**`sendBeacon()`** メソッドを使用すると、ユーザーエージェントに機会があるとき、**アンロードを遅延させたり次の操作の性能に影響を与えたりすることなく**データがウェブサーバーに非同期で送信されます。

次の例は、 **`sendBeacon()`** メソッドを使用してサーバーにデータを送信する実験的な分析コードパターンを示しています。

```js
window.addEventListener("unload", logData, false);

function logData() {
  navigator.sendBeacon("/log", analyticsData);
}
```

関連情報
----

* XMLHttpRequest の使用
* `navigator.sendBeacon`


XMLHttpRequest の使用 - Web API

XMLHttpRequest の使用
==================

このガイドでは、ウェブサイトとサーバーの間でデータ交換をするために、 `XMLHttpRequest` を使用して HTTP リクエストを発行する方法を紹介します。

`XMLHttpRequest` のよくある使用例やもっと分かりにくい使用例も含まれています。

HTTP リクエストを送るには、

1. `XMLHttpRequest` オブジェクトを作成し、
2. URL を開き、
3. リクエストを送信します。

トランザクションが完了すると、オブジェクトには結果の HTTP ステータスコードやレスポンスの本文などの有益な情報が格納されます。

```js
function reqListener() {
  console.log(this.responseText);
}

const req = new XMLHttpRequest();
req.addEventListener("load", reqListener);
req.open("GET", "http://www.example.org/example.txt");
req.send();
```

リクエストの種類
--------

`XMLHttpRequest` によって作成されたリクエストは、非同期または同期のいずれかの方法でデータを取得することが可能です。リクエストをどちらの方法で行うかは、 `XMLHttpRequest.open()` メソッドのオプションの `async` 引数（第 3 引数）で指示することができます。この引数を `true` にするか、指定しなければ `XMLHttpRequest` は非同期で処理され、それ以外だと同期的に扱われます。これら二つの種類のリクエストに関する詳細および使用例は、同期および非同期リクエストのページを参照してください。ウェブワーカー以外では同期リクエストを使用しないでください。

**メモ:** コンストラクター関数 `XMLHttpRequest` は XML 文書に限定されていません。 **"XML"** で始まっているのは、これが作成されたときに非同期データ交換に使用されていた主要な形式が XML であったからです。

レスポンスの取り扱い
----------

`XMLHttpRequest()` コンストラクターに定義されている response 属性は何種類かがあります。これらはクライアントに `XMLHttpRequest` にレスポンスのステータスに関する重要な情報を作るように指示します。テキスト以外のレスポンス型を扱う場合は、後の節で概説する操作や解析が入ることがあるかもしれません。

### responseXML プロパティの解析と操作

リモートの XML 文書のコンテンツを得るために `XMLHttpRequest` を使う場合、 `responseXML` プロパティが解釈済みの XML 文書を含む DOM オブジェクトとなります。これによって、操作や解析が難しくなる可能性があります。この XML 文書を解析するには主な 4 つの方法があります。

1. 部分を指すために XPath を使う。
2. 手動で XML を解釈およびシリアライズして文字列やオブジェクトにする。
3. `XMLSerializer` を使って **DOM ツリーを文字列やファイルに**シリアライズする。
4. 事前に XML 文書の中身が常に分かっている場合は `RegExp` を使うこともできます。改行を `RegExp` でスキャンする場合に、改行を除去した方がよく見えることもありますが、 XML コードが少しでも変更されると、メソッドは失敗しがちなため、このメソッドは「最後の手段」です。

**メモ:** `XMLHttpRequest` は `responseXML` プロパティを使用することによって、 HTML を解釈できるようになりました。この方法について学ぶには、 XMLHttpRequest における HTML の扱いについての記事をお読みください。

### HTML 文書を含む responseText プロパティの処理

`XMLHttpRequest` を使ってリモート HTML ウェブページのコンテンツを取得する場合、 `responseText` プロパティは生の HTML が入った文字列です。これは操作や解析が難しいことを示しています。この生の HTML 文字列を分析し解析するには、主に 3 つの方法があります。

1. XMLHttpRequest における HTML の扱いの記事で紹介されている `XMLHttpRequest.responseXML` プロパティを使用する。
2. 文書フラグメントの本体を `fragment.body.innerHTML` を通してコンテンツに挿入し、そのフラグメントの DOM を走査する。
3. 事前に HTML の `responseText` の中身が常に分かっている場合は `RegExp` を使うこともできます。改行を RegExp でスキャンする場合に、改行を除去した方がよく見えることもありますが、 HTML 文書が少しでも変更されると、メソッドは失敗しがちなため、このメソッドは「最後の手段」です。
バイナリーデータの扱い
-----------

`XMLHttpRequest` はテキストデータの送受信に最もよく使われますが、バイナリーコンテンツの送受信にも使えます。 `XMLHttpRequest` のレスポンスをバイナリーデータ送信に強制するためのテストされたメソッドがいくつかあります。この中には `XMLHttpRequest` オブジェクトの `overrideMimeType()` メソッドを活用して使える解決法としているものも入っています。

```js
const req = new XMLHttpRequest();
req.open("GET", url);
// バイナリー文字列として未処理のデータを取得する
req.overrideMimeType("text/plain; charset=x-user-defined");
/\* … \*/
```

しかし、もっと新しいテクニックも使用できます。 `responseType` 属性がいくつもの追加のコンテンツ型に対応するようになったので、バイナリーデータの送信や受信がずっと簡単になりました。

例えばこのスニペットでは、 `responseType` に "`arraybuffer`" を使用して、生のバイナリーデータを格納できる `ArrayBuffer` オブジェクトにリモートコンテンツを取得しています。

```js
const req = new XMLHttpRequest();

req.onload = (e) => {
  const arraybuffer = req.response; // responseText ではない
  /\* … \*/
};
req.open("GET", url);
req.responseType = "arraybuffer";
req.send();
```

その他の例は、バイナリーデータの送信と受信 ページを確認してください。

進捗の監視
-----

`XMLHttpRequest` は、リクエストが処理されている間に発生する様々なイベントを待受けする機能を提供しています。これには定期的な進捗の通知、エラーの通知、などが含まれます。

`XMLHttpRequest` の転送を監視する DOM `progress` イベントの対応は、 progress events 仕様に従います。このイベントは `ProgressEvent` インターフェイスを実装しています。進行中の転送の状態を特定するために監視することができる実際のイベントは、以下の通りです。

`progress`

受取済みのデータ量が変化したとき。

`load`

転送が完了したとき。すべてのデータが `response` に入っています。

```js
const req = new XMLHttpRequest();

req.addEventListener("progress", updateProgress);
req.addEventListener("load", transferComplete);
req.addEventListener("error", transferFailed);
req.addEventListener("abort", transferCanceled);

req.open();

// …

// サーバーからクライアントへの転送の進捗 (ダウンロード)
function updateProgress(event) {
  if (event.lengthComputable) {
    const percentComplete = (event.loaded / event.total) \* 100;
    // …
  } else {
    // 全体の長さが不明なため、進捗情報を計算できない
  }
}

function transferComplete(evt) {
  console.log("転送が完了しました。");
}

function transferFailed(evt) {
  console.log("ファイルの転送中にエラーが発生しました。");
}

function transferCanceled(evt) {
  console.log("ユーザーが転送をキャンセルしました。");
}
```

3-6 行目で `XMLHttpRequest` を使ってデータ転送を行うときに送られる色々なイベントへのためのイベントリスナーを追加しています。

**メモ:** イベントリスナーはリクエストの `open()` を呼び出す前に追加する必要があります。そうしないと `progress` イベントは発生しません。

この例では `updateProgress()` 関数で指定される進捗イベントハンドラーは、イベントの `total` および `loaded` フィールドで、転送すべき総バイト数とこれまでに転送したバイト数を受け取ります。ただし、`lengthComputable` フィールドが false の場合、合計の長さは分からないので 0 になります。

進捗イベントはダウンロード、アップロードの両方に存在します。ダウンロードのイベントは、上記サンプルのように、`XMLHttpRequest` オブジェクトそのもので発生します。アップロードのイベントは下記のように、 `XMLHttpRequest.upload` オブジェクトで発生します。

```js
const req = new XMLHttpRequest();

req.upload.addEventListener("progress", updateProgress);
req.upload.addEventListener("load", transferComplete);
req.upload.addEventListener("error", transferFailed);
req.upload.addEventListener("abort", transferCanceled);

req.open();
```

**メモ:** 進捗イベントは `file:` プロトコルでは利用できません。

progress イベントは、受信したデータの塊ごとに発生します。 progress イベントが発行される前に最後のパケットを受信して接続が閉じられた場合には、最後の塊でも発生します。この場合、 progress イベントは、そのパケットに対して load イベントが発生したときに自動的に発行されます。これで、 "progress" イベントを見るだけで、確実に進捗を監視できるようになりました。

ロードを終える 3 つの条件（`abort`, `load`, `error`のいずれか）を `loadend` イベントで検出することもできます。

```js
req.addEventListener("loadend", loadEnd);

function loadEnd(e) {
  console.log(
    "The transfer finished (although we don't know if it succeeded or not).",
  );
}
```

注意点として、 `loadend` イベントで受け取った情報から、どの条件で動作が終了したのかを確かめる方法はありません。しかし、これを使ってすべての転送終了シナリオにて行う必要のあるタスクを処理できます。

最終更新日の取得
--------

```js
function getHeaderTime() {
  console.log(this.getResponseHeader("Last-Modified")); // 有効な GMTString の日付または null
}

const req = new XMLHttpRequest();
req.open(
  "HEAD", // ヘッダーのみが必要であれば HEAD を使用する
  "yourpage.html",
);
req.onload = getHeaderTime;
req.send();
```

### 最終更新日付が変わった時に何かする

２つの関数を作ってみましょう。

```js
function getHeaderTime() {
  const lastVisit = parseFloat(
    window.localStorage.getItem(`lm\_${this.filepath}`),
  );
  const lastModified = Date.parse(this.getResponseHeader("Last-Modified"));

  if (isNaN(lastVisit) || lastModified > lastVisit) {
    window.localStorage.setItem(`lm\_${this.filepath}`, Date.now());
    isFinite(lastVisit) && this.callback(lastModified, lastVisit);
  }
}

function ifHasChanged(URL, callback) {
  const req = new XMLHttpRequest();
  req.open("HEAD" /\* use HEAD - we only need the headers! \*/, URL);
  req.callback = callback;
  req.filepath = URL;
  req.onload = getHeaderTime;
  req.send();
}
```

そしてテストします。

```js
// Let's test the file "yourpage.html"
ifHasChanged("yourpage.html", function (modified, visit) {
  console.log(
    `The page '${this.filepath}' has been changed on ${new Date(
 nModified,
 ).toLocaleString()}!`,
  );
});
```

現在のページが変更されたかどうかを知りたい場合は、 `document.lastModified` についての記事をお読みください。

サイトをまたがる XMLHttpRequest
-----------------------

現在のブラウザーは、オリジン間リソース共有 (Cross-Origin Resource Sharing, CORS) を実装することでサイト間リクエストに対応しています。サーバーがウェブアプリケーションのオリジンからのリクエストを許可するように構成されている場合のみ、 `XMLHttpRequest` は動作します。それ以外の場合は、 `INVALID_ACCESS_ERR` 例外が投げられます。

キャッシュをバイパスする
------------

ブラウザー間で互換性のある、キャッシュをバイパスするアプローチは、 URL にタイムスタンプを追加することで、適切に "?" 又は "&" を付け加えます。例えば以下のようにします。
```

http://example.com/bar.html -> http://example.com/bar.html?12345
http://example.com/bar.html?foobar=baz -> http://example.com/bar.html?foobar=baz&12345
```

ローカルのキャッシュは URL によって索引づけられるため、これですべてのリクエストが固有のものとなり、それによってキャッシュをバイパスします。

以下のコードを使用すると、自動的に URL を調整することができます。

```js
const req = new XMLHttpRequest();

req.open("GET", url + (/\?/.test(url) ? "&" : "?") + new Date().getTime());
req.send(null);
```

セキュリティ
------

サイト間スクリプトを有効にするための推奨される方法は、 XMLHttpRequest へのレスポンスの中で HTTP の `Access-Control-Allow-Origin` ヘッダーを使用することです。

### XMLHttpRequests の停止

XMLHttpRequest が `status=0` および `statusText=null` を受信して終了すると、リクエストを実行することが許可されていないことを意味します。これは未送信 (`UNSENT`) 状態です。この原因の多くは、 XMLHttpRequest が `open()` の時に `XMLHttpRequest` のオリジン (XMLHttpRequest が作成された場所) が変更されたことによるものです。これは例えば、 XMLHttpRequest を持ったページで onunload イベントが発生し、ウィンドウが閉じようとしている時に XMLHttpRequest が作成され、ウィンドウがフォーカスを失って他のウィンドウがフォーカスを得たときにリクエストの送信（言い換えれば `open()`）が行なわれた場合に発生することがあります。この問題を防ぐ最も効果的な方法は、新しいウィンドウの `DOMActivate` イベントのリスナーを、 `unload` イベントが発生したときに設定することです。

仕様書
---

| Specification |
| --- |
| XMLHttpRequest Standard # interface-xmlhttprequest |

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

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

関連情報
----

* MDN の AJAX 入門
* XMLHttpRequest における HTML の扱い
* HTTP アクセス制御
* XMLHttpRequest - REST and the Rich User Experience
* The `XMLHttpRequest` object: WHATWG specification


AudioBufferSourceNode.start() - Web API

AudioBufferSourceNode.start()
=============================

`start()` は `AudioBufferSourceNode` インターフェイスのメソッドで、
 このメソッドは、バッファーに含まれる音声データの再生を予約したり、すぐに再生を開始したりするために使用されます。

構文
--

```js
start(when)
start(when, offset)
start(when, offset, duration)
```

### 引数

`when` 省略可

音が鳴り始めるべき時刻（秒単位）。 `AudioContext` が使用するのと同じ時間座標系で指定します。もし `when` が (`AudioContext.currentTime` よりも小さいか、 0 であれば、音の再生はすぐに開始されます。**既定値は 0 です。**

`offset` 省略可

音声バッファー内で再生を始めるべき時刻を、 `AudioContext` と同じ時間座標系で秒単位で指定したオフセットです。例えば、 10 秒の音声クリップの半分から再生を始めるには、 `offset` は 5 となります。既定値である 0 は、音声バッファの先頭から再生を始めます。再生される音声の終わりを過ぎたオフセット（音声バッファーの `duration` や `loopEnd` 属性に基づく）は、許容範囲内の最大値に暗黙に収められます。サウンドへのオフセットの計算は、現在の再生速度ではなく、音声バッファー本来のサンプルレートを使用して行われるため、サウンドが通常の 2 倍の速度で再生されている場合でも、 10 秒の音声バッファーの中間の点は 5 となります。

`duration` 省略可

サウンドの再生時間を秒単位で指定します。この引数が指定されなかった場合、サウンドは自然に終了するか、 `stop()` メソッドを使用して停止されるまで再生されます。この引数を使用すると、 `start(when, offset)` を呼び出してから `stop(when+duration)` を使用するのと機能的に同じになります。

### 返値

なし (`undefined`)。

### 例外

`TypeError`

3 つの時間引数のうち 1 つ以上に負の値が指定された場合に発生します。時間物理学の法則を改ざんしようとしないでください。

`InvalidStateError` `DOMException`

`start()` が既に呼び出されていた場合に発生します。この関数は `AudioBufferSourceNode` が生きている間に一度だけ呼び出すことができます。

例
-

最も単純な例は、音声バッファー再生を最初から始めるだけです。この場合、引数を指定する必要はありません。

```js
source.start();
```

次はそれよりも複雑な再生方法です。1 秒待った後、音声バッファーの 3 秒経過した位置から、10 秒間再生します。

```js
source.start(audioCtx.currentTime + 1, 3, 10);
```

**メモ:** `start()` の使い方の完全な例は `AudioContext.decodeAudioData()` を参照してください。コードをすぐに実行することや、ソースコードを閲覧することもできます。

仕様書
---

| Specification |
| --- |
| Web Audio API # dom-audiobuffersourcenode-start |

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

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

関連情報
----

* ウェブオーディオ API の使用


AudioBufferSourceNode() - Web API

AudioBufferSourceNode()
=======================

**`AudioBufferSourceNode()`** コンストラクターは、新しい `AudioBufferSourceNode` オブジェクトインスタンスを生成します。

構文
--

```js
new AudioBufferSourceNode(context, options)
```

### 引数

`context`

`AudioContext` への参照。

`options` 省略可

以下のオプションです。

`buffer`

再生される `AudioBuffer` のインスタンス。

`detune`

音声ストリームのレンダリング速度を調整するためのセント単位の値。公称範囲は（-∞ から +∞）です。既定では `0` です。

`loop`

 論理値で、音声をループ再生させるかどうかを示します。
 既定値は `false` です。ループが再生中に動的に変更された場合、新しい値は音声の次の処理ブロックに反映されます。

`loopEnd`

オプションで、 loop 属性が `true` である場合にループを終了させる値を秒単位で指定します。既定では `0` です。この値は、ループの中身とは関係ありません。ループを構成するサンプルフレームは、 `loopStart` から `loopEnd`-(1/`sampleRate`) までの値で実行されます。この値は 0 からバッファーの持続時間の間に設定するのが賢明です。もし `loopEnd` が 0 よりも小さければ、ループは 0 で終わり、もし `loopEnd` がバッファーの持続時間よりも大きければ、ループはバッファーの終端で終了します。この属性は、バッファのサンプルレートを掛け、最も近い整数値に丸めることで、バッファー内の正確なサンプルフレームオフセットに変換されます。そのため、この属性の動作は `playbackRate` 引数の値には依存しません。

`loopStart`

オプションで、 loop 属性が `true` の場合にループを始める値を秒単位で指定します。既定では `0` です。0 とバッファーの持続時間の間の値に設定するのが賢明です。もし `loopStart` が 0 よりも小さい場合、ループは 0 から始まります。もし `loopStart` がバッファーの持続時間よりも大きい場合、ループはバッファーの終わりから始まります。この属性は、バッファーのサンプルレートを掛け、最も近い整数値に丸めることで、バッファー内の正確なサンプルフレームオフセットに変換されます。そのため、この属性の動作は `playbackRate` 引数の値には依存しません。

`playbackRate`

音声ストリームをレンダリングする速度を指定します。既定値では `1` です。この引数は k-rate です。離調との複合引数です。公称範囲は（-∞ から +∞）です。

`channelCount`

ノードへの任意の入力への接続をアップミキシングおよびダウンミキシングする際に使用されるチャンネル数を決定するために使用される整数を表します。（詳細は `AudioNode.channelCount` を参照。）使用方法と正確な定義は、 `channelCountMode` の値に依存します。

`channelCountMode`

ノードの入出力間でチャンネルを一致させる方法を記述した列挙型の値を表します。（既定値を含む詳細情報は `AudioNode.channelCountMode` を参照してください。）

`channelInterpretation`

チャンネルの意味を表現する列挙値を記述します。この解釈により、音声のアップミキシングおよびダウンミキシングがどのように行われるかが定義されます。使用可能な値は `"speakers"` または `"discrete"` です。（既定値で記載される詳細な情報は `AudioNode.channelCountMode` を参照してください。）

### 返値

新しい `AudioBufferSourceNode` オブジェクトインスタンスです。

仕様書
---

| Specification |
| --- |
| Web Audio API # dom-audiobuffersourcenode-constructor-audiobuffersourcenode |

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

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


AudioBufferSourceNode.playbackRate - Web API

AudioBufferSourceNode.playbackRate
==================================

**`playbackRate`** は `AudioBufferSourceNode` インターフェイスのプロパティで、
 このプロパティは、音声資産の再生速度を定義する k-rate `AudioParam` です。

 1.0 の値は、そのサンプリングレートと同じ速度で再生することを示し、 1.0 より小さい値は、よりゆっくりと、1.0 より大きい値は、通常より速く音声を再生することになります。既定値は `1.0` です。
 他の値に設定された場合、`AudioBufferSourceNode` は出力に送る前に音声を再サンプリングします。

値
-

この `value` は、音声の再生レートを元のサンプリングレートに対する十進数の割合で示す浮動小数点型の値です。

44.1 kHz （44,100 サンプル毎秒）でサンプリングされた音声を含むサウンドバッファーを考えてみましょう。いくつかの `playbackRate` の値で何ができるかを見てみましょう。

* `playbackRate` を 1.0 にすると、通常の速度、 44,100 Hz で再生します。
* `playbackRate` を 0.5 にすると、半分の速度、 22,050 Hz で再生します。
* `playbackRate` を 2.0 は音声の再生レートを倍にして 88,200 Hz で再生します。
例
-

この例では、 `AudioContext.decodeAudioData()` 関数を使用して音声トラックをデコードし、 `AudioBufferSourceNode` に入れています。音声の再生と停止にはボタンが指定され、`playbackRate`、`loopStart`、`loopEnd` のプロパティをその場で変更するためにスライダーコントロールが使用されます。

**メモ:** 動作する完全な例は、このコードをライブで実行するか、ソースを表示することができます。.

```html
<input
 class="playback-rate-control"
 type="range"
 min="0.25"
 max="3"
 step="0.05"
 value="1" />
<span class="playback-rate-value">1.0</span>
```

```js
function getData() {
  source = audioCtx.createBufferSource();
  request = new XMLHttpRequest();

  request.open("GET", "viper.ogg", true);

  request.responseType = "arraybuffer";

  request.onload = () => {
    const audioData = request.response;

    audioCtx.decodeAudioData(
      audioData,
      (buffer) => {
        myBuffer = buffer;
        source.buffer = myBuffer;
        source.playbackRate.value = playbackControl.value;
        source.connect(audioCtx.destination);
        source.loop = true;
      },

      (e) => console.error(`Error with decoding audio data: ${e.err}`),
    );
  };

  request.send();
}

// wire up buttons to stop and play audio, and range slider control

play.onclick = () => {
  getData();
  source.start(0);
  play.setAttribute("disabled", "disabled");
  playbackControl.removeAttribute("disabled");
};

stop.onclick = () => {
  source.stop(0);
  play.removeAttribute("disabled");
  playbackControl.setAttribute("disabled", "disabled");
};

playbackControl.oninput = () => {
  source.playbackRate.value = playbackControl.value;
  playbackValue.innerHTML = playbackControl.value;
};
```

仕様書
---

| Specification |
| --- |
| Web Audio API # dom-audiobuffersourcenode-playbackrate |

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

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

関連情報
----

* ウェブオーディオ API の使用
* ウェブオーディオ API


AudioBufferSourceNode.detune - Web API

AudioBufferSourceNode.detune
============================

**`detune`** は `AudioBufferSourceNode` インターフェイスのプロパティで、k-rate の `AudioParam` 再生時の離調をセント単位で表します。

例えば、 +100 と -100 の値は半音ずつ上下に離調し、 +1200 と -1200 の値は 1 オクターブずつ上下に離調します。

値
-

 A k-rate `AudioParam`
 whose value indicates the detuning of oscillation in cents.

**メモ:** `AudioParam` は読み取り専用の値を返しますが、値は読み取り専用ではありません。

例
-

```js
const audioCtx = new AudioContext();

const channelCount = 2;
const frameCount = audioCtx.sampleRate \* 2.0; // 2 seconds

const myArrayBuffer = audioCtx.createBuffer(
  channelCount,
  frameCount,
  audioCtx.sampleRate,
);

for (let channel = 0; channel < channelCount; channel++) {
  const nowBuffering = myArrayBuffer.getChannelData(channel);
  for (let i = 0; i < frameCount; i++) {
    nowBuffering[i] = Math.random() \* 2 - 1;
  }
}

const source = audioCtx.createBufferSource();
source.buffer = myArrayBuffer;
source.connect(audioCtx.destination);
source.detune.value = 100; // value in cents
source.start();
```

仕様書
---

| Specification |
| --- |
| Web Audio API # dom-audiobuffersourcenode-detune |

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

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

関連情報
----

* ウェブオーディオ API の使用
* ウェブオーディオ API


AudioBufferSourceNode.loopStart - Web API

AudioBufferSourceNode.loopStart
===============================

**`loopStart`** は `AudioBufferSourceNode` インターフェイスのプロパティで、 `AudioBuffer` の中で再生再開を行うべき場所を秒単位で示す浮動小数点数値です。

`loopStart` プロパティの既定値は `0` です。

値
-

浮動小数点数で、再生中に各ループを始めるべき音声バッファーへのオフセットを秒単位で示します。この値は `loop` 引数が `true` のときのみ使用されます。

例
-

この例では、 `AudioContext.decodeAudioData()` 関数を使用して音声トラックをデコードし、 `AudioBufferSourceNode` に入れています。音声の再生と停止にはボタンが指定され、`playbackRate`、`loopStart`、`loopEnd` のプロパティをその場で変更するためにスライダーコントロールが使用されます。

音声が最後まで再生されるとループしますが、 `loopStart` と `loopEnd` を変更することによってループの長さを制御することができます。例えば、それらの値をそれぞれ 20 と 25 に設定すると、音声はトラックの 20 秒から 25 秒の間でループを始めることになります。

**メモ:** 動作する完全な例は、このコードをライブで実行するか、ソースを表示することができます。.

```js
function getData() {
  source = audioCtx.createBufferSource();
  request = new XMLHttpRequest();

  request.open("GET", "viper.ogg", true);
  request.responseType = "arraybuffer";

  request.onload = () => {
    const audioData = request.response;

    audioCtx.decodeAudioData(
      audioData,
      (buffer) => {
        myBuffer = buffer;
        songLength = buffer.duration;
        source.buffer = myBuffer;
        source.playbackRate.value = playbackControl.value;
        source.connect(audioCtx.destination);
        source.loop = true;

        loopstartControl.setAttribute("max", Math.floor(songLength));
        loopendControl.setAttribute("max", Math.floor(songLength));
      },

      (e) => console.error(`Error with decoding audio data: ${e.err}`),
    );
  };

  request.send();
}

// …

loopstartControl.oninput = () => {
  source.loopStart = loopstartControl.value;
  loopstartValue.innerHTML = loopstartControl.value;
};

loopendControl.oninput = () => {
  source.loopEnd = loopendControl.value;
  loopendValue.innerHTML = loopendControl.value;
};
```

仕様書
---

| Specification |
| --- |
| Web Audio API # dom-audiobuffersourcenode-loopstart |

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

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

関連情報
----

* ウェブオーディオ API
* ウェブオーディオ API の使用


AudioBufferSourceNode.buffer - Web API

AudioBufferSourceNode.buffer
============================

**`buffer`** は `AudioBufferSourceNode` インターフェイスのプロパティで、音声データのソースとして `AudioBuffer` を使用して音声を再生する機能を提供します。

`buffer` プロパティに `null` という値を設定すると、ノードは無音を含む単一のチャンネルを生成します（つまり、すべてのサンプルが 0 になります）。

値
-

ノードが再生する音を表すデータを格納した `AudioBuffer`。

例
-

**メモ:** 動作する完全な例は、このコードをライブ実行またはソースを閲覧してください。

```js
const myArrayBuffer = audioCtx.createBuffer(2, frameCount, audioCtx.sampleRate);

button.onclick = () => {
  // Fill the buffer with white noise;
  //just random values between -1.0 and 1.0
  for (let channel = 0; channel < channels; channel++) {
    // This gives us the actual ArrayBuffer that contains the data
    const nowBuffering = myArrayBuffer.getChannelData(channel);
    for (let i = 0; i < frameCount; i++) {
      // Math.random() is in [0; 1.0]
      // audio needs to be in [-1.0; 1.0]
      nowBuffering[i] = Math.random() \* 2 - 1;
    }
  }

  // Get an AudioBufferSourceNode.
  // This is the AudioNode to use when we want to play an AudioBuffer
  const source = audioCtx.createBufferSource();
  // set the buffer in the AudioBufferSourceNode
  source.buffer = myArrayBuffer;
};
```

仕様書
---

| Specification |
| --- |
| Web Audio API # dom-audiobuffersourcenode-buffer |

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

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

関連情報
----

* ウェブオーディオ API の使用
* ウェブオーディオ API


AudioBufferSourceNode.loop - Web API

AudioBufferSourceNode.loop
==========================

`loop` は `AudioBufferSourceNode` のプロパティで、 `AudioBuffer` の末端に達した時に、音声を繰り返し再生するべきかを示す論理値です。

`loop` プロパティの既定値は `false`です。

### 値

論理値で、繰り返しが有効な場合は `true` 、それ以外は `false` です。

ループが有効である場合、 `start()` が呼ばれると音声は開始点として指定された場所から再生されます。 `loopEnd` で指定された場所に達すると、音声は `loopStart` で指定された地点に戻って再生され続けます。

例
-

この例では、 `AudioContext.decodeAudioData()` 関数は音声トラックをデコードし `AudioBufferSourceNode` に追加するために使用されています。再生・停止のためにボタンが配置され、スライダーが `playbackRate` プロパティを逐次変更するために使用されています。音声はループして再生されます。

**メモ:** 実際に動作する例を見る (または、ソースコードを見る)ことができます。

```js
function getData() {
  source = audioCtx.createBufferSource();
  request = new XMLHttpRequest();

  request.open("GET", "viper.ogg", true);

  request.responseType = "arraybuffer";

  request.onload = () => {
    const audioData = request.response;

    audioCtx.decodeAudioData(
      audioData,
      (buffer) => {
        myBuffer = buffer;
        source.buffer = myBuffer;
        source.playbackRate.value = playbackControl.value;
        source.connect(audioCtx.destination);
        source.loop = true;
      },

      (e) => console.error(`Error with decoding audio data: ${e.err}`),
    );
  };

  request.send();
}

// wire up buttons to stop and play audio, and range slider control

play.onclick = () => {
  getData();
  source.start(0);
  play.setAttribute("disabled", "disabled");
  playbackControl.removeAttribute("disabled");
};
```

仕様書
---

| Specification |
| --- |
| Web Audio API # dom-audiobuffersourcenode-loop |

ブラウザーの対応
--------

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

関連情報
----

* ウェブオーディオ API
* ウェブオーディオ API の使用
* `AudioBufferSourceNode`


AudioBufferSourceNode.loopEnd - Web API

AudioBufferSourceNode.loopEnd
=============================

`loopEnd` は `AudioBufferSourceNode` インターフェイスのプロパティで、 `AudioBuffer` の再生が `loopStart` プロパティで示される時刻にループで戻るオフセットを秒単位で指定する浮動小数点の数値です。
 これは `loop` プロパティが `true` である場合にのみ使用されます。

値
-

各ループがループの最初に戻る（つまり、現在の再生時刻が `AudioBufferSourceNode.loopStart` にリセットされる）音声バッファー内のオフセットを、秒単位で示した浮動小数点の数値です。このプロパティは `loop` プロパティが `true` である場合にのみ使用されます。

既定値は 0 です。

例
-

この例では、 `AudioContext.decodeAudioData()` 関数を使用して音声トラックをデコードし、 `AudioBufferSourceNode` へ格納しています。音声の再生と停止にはボタンが指定され、`playbackRate`、`loopStart`、`loopEnd` のプロパティをその場で変更するためにスライダーコントロールが使用されます。

音声を最後まで再生するとループしますが、 `loopStart` と `loopEnd` を変更することによってループの長さを制御することができます。例えば、それらの値をそれぞれ 20 と 25 に設定し、再生を始めると、 25 秒の位置に到達するまで正常に再生されます。そして、現在の再生位置は 20 秒の位置に戻り、 25 秒の位置まで無限に（少なくとも `stop()` が呼び出されるまで）再生し続けるループとなります。

**メモ:** 動作する完全な例は、このコードをライブで実行するか、ソースを表示することができます。.

```js
function getData() {
  source = audioCtx.createBufferSource();
  request = new XMLHttpRequest();

  request.open("GET", "viper.ogg", true);

  request.responseType = "arraybuffer";

  request.onload = () => {
    const audioData = request.response;

    audioCtx.decodeAudioData(
      audioData,
      (buffer) => {
        myBuffer = buffer;
        songLength = buffer.duration;
        source.buffer = myBuffer;
        source.playbackRate.value = playbackControl.value;
        source.connect(audioCtx.destination);
        source.loop = true;

        loopstartControl.setAttribute("max", Math.floor(songLength));
        loopendControl.setAttribute("max", Math.floor(songLength));
      },

      (e) => console.error(`Error with decoding audio data: ${e.err}`),
    );
  };

  request.send();
}

// …

loopstartControl.oninput = () => {
  source.loopStart = loopstartControl.value;
  loopstartValue.innerHTML = loopstartControl.value;
};

loopendControl.oninput = () => {
  source.loopEnd = loopendControl.value;
  loopendValue.innerHTML = loopendControl.value;
};
```

仕様書
---

| Specification |
| --- |
| Web Audio API # dom-audiobuffersourcenode-loopend |

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

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

関連情報
----

* ウェブオーディオ API の使用
* ウェブオーディオ API


HTMLDialogElement: returnValue プロパティ - Web API

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

Baseline 2022
-------------

Newly availableSince March 2022, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

* Learn more
* See full compatibility
* Report feedback
**`returnValue`** は `HTMLDialogElement` インターフェイスのプロパティで、このダイアログ (`<dialog>`) の返値を取得または設定します。ふつう、閉じる際にどのボタンが押されたかを示します。

値
-

ダイアログの `returnValue` を表す文字列です。

例
-

次の例では、フォームの入った `<dialog>` を `showModal()` メソッドで開くためのボタンを表示しています。スクリプトは `returnvalue` に初期値を割り当てています。そこから、確認ボタンで検証つきフォームを送信し、「×」ボタンで検証なしでフォームを送信します。`method="dialog"` でフォームを送信すると、ダイアログが閉じられ、返値には送信ボタンの `name` （もしあれば）が設定されます。リセットボタンにはダイアログを閉じるイベントハンドラーがありますが、これは `returnValue` には何の影響もありません。`Esc` キーでダイアログを閉じることもできません。

```html
<!-- フォームの入った単純なポップアップのダイアログボックス -->
<dialog id="favDialog">
  <form method="dialog">
    <input
 type="submit"
 aria-label="close"
 value="X"
 name="Xbutton"
 formnovalidate />
    <p>
      <label
 >Favorite animal:
        <select name="favAnimal" required>
          <option></option>
          <option>Brine shrimp</option>
          <option>Red panda</option>
          <option>Spider monkey</option>
        </select>
      </label>
    </p>
    <menu>
      <button type="reset" value="resetBtn">Reset</button>
      <button type="submit" value="confirmBtn">Confirm</button>
    </menu>
  </form>
</dialog>

<p>
  <button id="openDialog">Open Dialog</button>
</p>
<p id="text"></p>

<script>
 (() => {
 const openDialog = document.getElementById("openDialog");
 const dialog = document.getElementById("favDialog");
 const text = document.getElementById("text");
 const reset = document.querySelector("[type='reset']");
 dialog.returnValue = "initialValue";

 function openCheck(dialog) {
 if (dialog.open) {
 text.innerText = "Dialog open";
 } else {
 text.innerText = "Dialog closed";
 }
 }

 function handleUserInput(returnValue) {
 if (!returnValue) {
 text.innerText += ". There was no return value";
 } else {
 text.innerText += ". Return value: " + returnValue;
 }
 }

 // "Open Dialog" ボタンは <dialog> をモーダルに開く
 openDialog.addEventListener("click", () => {
 dialog.showModal();
 openCheck(dialog);
 handleUserInput(dialog.returnValue);
 });

 reset.addEventListener("click", () => {
 dialog.close();
 });

 // ダイアログが閉じられたとき、どのように閉じられたかにかかわらず
 dialog.addEventListener("close", () => {
 openCheck(dialog);
 handleUserInput(dialog.returnValue);
 });
 })();
</script>
<style>
 [aria-label="close"] {
 appearance: none;
 border-radius: 50%;
 border: 1px solid;
 float: right;
 }
</style>
```

### 結果

仕様書
---

| Specification |
| --- |
| HTML Standard # dom-dialog-returnvalue-dev |

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

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

関連情報
----

* このインターフェイスを実装している HTML 要素: `<dialog>`


HTMLDialogElement: close() メソッド - Web API

HTMLDialogElement: close() メソッド
===============================

Baseline 2022
-------------

Newly availableSince March 2022, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

* Learn more
* See full compatibility
* Report feedback

**`close()`** は `HTMLDialogElement` インターフェイスのメソッドで、このダイアログ (`<dialog>`) を閉じます。
 引数としてオプションの文字列を渡すことができ、このダイアログの `returnValue` を更新します。

構文
--

```js
close()
close(returnValue)
```

### 引数

`returnValue` 省略可

文字列で、このダイアログの `HTMLDialogElement.returnValue` を更新する値を表します。

### 返値

なし (`undefined`)。

例
-

 次の例は単純なボタンですが、クリックするとフォームを含む `<dialog>` を `showModal()` メソッドで開きます。
 そこから *X* ボタンをクリックしてダイアログを閉じたり（ `HTMLDialogElement.close()` メソッドで）、submit ボタンでフォームを送信したりすることができます。

```html
<!-- Simple pop-up dialog box, containing a form -->
<dialog id="favDialog">
  <form method="dialog">
    <button id="close" aria-label="close" formnovalidate>X</button>
    <section>
      <p>
        <label for="favAnimal">Favorite animal:</label>
        <select id="favAnimal" name="favAnimal">
          <option></option>
          <option>Brine shrimp</option>
          <option>Red panda</option>
          <option>Spider monkey</option>
        </select>
      </p>
    </section>
    <menu>
      <button type="reset">Reset</button>
      <button type="submit">Confirm</button>
    </menu>
  </form>
</dialog>

<menu>
  <button id="updateDetails">Update details</button>
</menu>

<script>
 (() => {
 const updateButton = document.getElementById("updateDetails");
 const closeButton = document.getElementById("close");
 const dialog = document.getElementById("favDialog");
 dialog.returnValue = "favAnimal";

 function openCheck(dialog) {
 if (dialog.open) {
 console.log("Dialog open");
 } else {
 console.log("Dialog closed");
 }
 }

 // Update button opens a modal dialog
 updateButton.addEventListener("click", () => {
 dialog.showModal();
 openCheck(dialog);
 });

 // Form close button closes the dialog box
 closeButton.addEventListener("click", () => {
 dialog.close("animalNotChosen");
 openCheck(dialog);
 });
 })();
</script>
```

 [X] ボタンが `type="submit"` であったなら、JavaScript を必要とせずにダイアログが閉じられたはずです。
 フォームを送信すると、フォームのメソッドが `dialog` であれば、それが入った `<dialog>` を閉じるので、「閉じる」ボタンは必要ありません。

### 結果

仕様書
---

| Specification |
| --- |
| HTML Standard # dom-dialog-close-dev |

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

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

関連情報
----

* このインターフェイスを実装している HTML 要素: `<dialog>`


HTMLDialogElement: open プロパティ - Web API

HTMLDialogElement: open プロパティ
=============================

Baseline 2022
-------------

Newly availableSince March 2022, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

* Learn more
* See full compatibility
* Report feedback
**`open`** は `HTMLDialogElement` インターフェイスのプロパティで、HTML の `open` 属性を反映した論理値です。これは `<dialog>` が操作できる状態であるかどうかを示します。

値
-

論理値で、HTML の `open` 属性の状態を表します。`true` は設定されており、従ってダイアログは表示されています。`false` は設定されておらず、従ってダイアログは表示されていません。

このプロパティは読み取り専用になりました。プログラムにより値を設定してダイアログを表示または非表示にすることは可能です。

例
-

 以下の例では、クリックするとフォームを含む `<dialog>` を `showModal()` メソッドで開くための単純なボタンを示しています。
 そこから *Cancel* ボタンをクリックしてダイアログを閉じたり（`HTMLDialogElement.close()` メソッドで）、送信ボタンでフォームを送信したりすることができます。

```html
<!-- Simple pop-up dialog box -->
<dialog id="dialog">
  <form method="dialog">
    <button type="submit">Close</button>
  </form>
</dialog>

<p>
  <button id="openDialog">Open Dialog</button>
</p>
<p id="dialogStatus"></p>

<script>
 (() => {
 const openDialog = document.getElementById("openDialog");
 const dialog = document.getElementById("dialog");
 const text = document.getElementById("dialogStatus");

 function openCheck(dialog) {
 if (dialog.open) {
 text.innerText = "Dialog open";
 } else {
 text.innerText = "Dialog closed";
 }
 }

 // Update button opens a modal dialog
 openDialog.addEventListener("click", () => {
 dialog.showModal();
 openCheck(dialog);
 });

 dialog.addEventListener("close", () => {
 openCheck(dialog);
 });
 })();
</script>
```

### 結果

仕様書
---

| Specification |
| --- |
| HTML Standard # dom-dialog-open |

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

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

関連情報
----

* このインターフェイスを実装している HTML 要素: `<dialog>`


HTMLDialogElement: showModal() メソッド - Web API

HTMLDialogElement: showModal() メソッド
===================================

Baseline 2022
-------------

Newly availableSince March 2022, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

* Learn more
* See full compatibility
* Report feedback
**`showModal()`** は `HTMLDialogElement` インターフェイスのメソッドで、ダイアログをモーダルに、見えるように他のダイアログの最も上に表示します。これは 最上位レイヤー (en-US) の中に `::backdrop` 擬似要素とともに表示されます。ダイアログの外の操作はブロックされ、ダイアログの外のコンテンツは不活性にレンダリングされます。

構文
--

```js
showModal()
```

### 引数

なし。

### 返値

なし (`undefined`)。

### Exceptions

`InvalidStateError` `DOMException`

ダイアログが既に開いている場合（すなわち、`open` 属性が既に `<dialog>` 要素に設定されている場合）、またはダイアログが既に示されているポップオーバーである場合も発生します。

例
-

### モーダルダイアログを開く

次の例は、クリックするとフォームを含むモーダル `<dialog>` を `HTMLDialogElement.showModal()` 関数で開くボタンを示しています。開いている間、モーダルダイアログのコンテンツ以外は不活性になります。ここから、*Cancel* ボタンをクリックしてダイアログを閉じたり（`HTMLDialogElement.close()` 関数で）、submit ボタンによってフォームを送信したりすることができます。キャンセルボタンを選択するとダイアログが閉じられ、`close` イベントが作成されますが、`cancel` イベントは作成されません。

#### HTML

```html
<!-- pop-up dialog box, containing a form -->
<dialog id="favDialog">
  <form method="dialog">
    <p>
      <label for="favAnimal">Favorite animal:</label>
      <select id="favAnimal" name="favAnimal">
        <option></option>
        <option>Brine shrimp</option>
        <option>Red panda</option>
        <option>Spider monkey</option>
      </select>
    </p>
    <div>
      <button id="cancel" type="reset">Cancel</button>
      <button type="submit">Confirm</button>
    </div>
  </form>
</dialog>

<div>
  <button id="updateDetails">Update details</button>
</div>
```

#### JavaScript

```js
const updateButton = document.getElementById("updateDetails");
const cancelButton = document.getElementById("cancel");
const dialog = document.getElementById("favDialog");
dialog.returnValue = "favAnimal";

function openCheck(dialog) {
  if (dialog.open) {
    console.log("Dialog open");
  } else {
    console.log("Dialog closed");
  }
}

// Update button opens a modal dialog
updateButton.addEventListener("click", () => {
  dialog.showModal();
  openCheck(dialog);
});

// Form cancel button closes the dialog box
cancelButton.addEventListener("click", () => {
  dialog.close("animalNotChosen");
  openCheck(dialog);
});
```

#### 結果

仕様書
---

| Specification |
| --- |
| HTML Standard # dom-dialog-showmodal-dev |

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

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

関連情報
----

* このインターフェイスを実装している HTML 要素: `<dialog>`


HTMLDialogElement: show() メソッド - Web API

HTMLDialogElement: show() メソッド
==============================

Baseline 2022
-------------

Newly availableSince March 2022, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

* Learn more
* See full compatibility
* Report feedback
**`show()`** は `HTMLDialogElement` インターフェイスのメソッドで、ダイアログをモードレスに表示します。すなわち、ダイアログの外側のコンテンツも操作できる状態にします。

構文
--

```js
show()
```

### 引数

なし。

### 返値

なし (`undefined`)。

例
-

次の例は単純なボタンで、クリックするとフォームを含むダイアログ (`<dialog>`) を `show()` メソッドで開きます。ここから、*Cancel* ボタンをクリックしてダイアログを閉じたり（`HTMLDialogElement.close()` メソッドで）、submit ボタンでフォームを送信したりすることができます。

```html
<!-- Simple pop-up dialog box, containing a form -->
<dialog id="favDialog">
  <form method="dialog">
    <section>
      <p>
        <label for="favAnimal">Favorite animal:</label>
        <select id="favAnimal" name="favAnimal">
          <option></option>
          <option>Brine shrimp</option>
          <option>Red panda</option>
          <option>Spider monkey</option>
        </select>
      </p>
    </section>
    <menu>
      <button id="cancel" type="reset">Cancel</button>
      <button type="submit">Confirm</button>
    </menu>
  </form>
</dialog>

<menu>
  <button id="updateDetails">Update details</button>
</menu>

<script>
 (() => {
 const updateButton = document.getElementById("updateDetails");
 const cancelButton = document.getElementById("cancel");
 const dialog = document.getElementById("favDialog");
 dialog.returnValue = "favAnimal";

 function openCheck(dialog) {
 if (dialog.open) {
 console.log("Dialog open");
 } else {
 console.log("Dialog closed");
 }
 }

 // Update button opens a modeless dialog
 updateButton.addEventListener("click", () => {
 dialog.show();
 openCheck(dialog);
 });

 // Form cancel button closes the dialog box
 cancelButton.addEventListener("click", () => {
 dialog.close("animalNotChosen");
 openCheck(dialog);
 });
 })();
</script>
```

仕様書
---

| Specification |
| --- |
| HTML Standard # dom-dialog-show-dev |

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

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

関連情報
----

* このインターフェイスを実装している HTML 要素: `<dialog>`


HTMLDialogElement: close イベント - Web API

HTMLDialogElement: close イベント
=============================

Baseline 2022
-------------

Newly availableSince March 2022, this feature works across the latest devices and browser versions. This feature might not work in older devices or browsers.

* Learn more
* See full compatibility
* Report feedback
`close` イベントは `HTMLDialogElement` オブジェクト上で、これが表すダイアログ (`<dialog>`) が閉じられたときに発生します。

このイベントはキャンセル不可で、バブリングしません。

構文
--

このイベント名を `addEventListener()` などのメソッドで使用したり、イベントハンドラープロパティを設定したりします。

```js
addEventListener("close", (event) => {});

onclose = (event) => {};
```

イベント型
-----

一般的な `Event` です。

例
-

### ライブ例

#### HTML

```html
<dialog class="example-dialog">
  <form method="dialog">
    <button>Close via method="dialog"</button>
  </form>
  <button class="close">Close via .close() method</button>
  <p>Or hit the <kbd>Esc</kbd> key</p>
</dialog>

<button class="open-dialog">Open dialog</button>

<div class="result"></div>
```

```
button,
div {
  margin: 0.5rem;
}
```

#### JavaScript

```js
const result = document.querySelector(".result");

const dialog = document.querySelector(".example-dialog");
dialog.addEventListener("close", (event) => {
  result.textContent = "dialog was closed";
});

const openDialog = document.querySelector(".open-dialog");
openDialog.addEventListener("click", () => {
  dialog.showModal();
  result.textContent = "";
});

const closeButton = document.querySelector(".close");
closeButton.addEventListener("click", () => {
  dialog.close();
});
```

#### 結果

仕様書
---

| Specification |
| --- |
| HTML Standard # event-close |

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

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

関連情報
----

* HTML の `<dialog>` 要素


画面キャプチャ API の使用 - Web API

画面キャプチャ API の使用
===============

この記事では、画面キャプチャ API とその `getDisplayMedia()` メソッドを使用して、 WebRTC 会議セッション中に画面の一部または全部をストリーミング、録音、共有用に取得する方法を検証していきます。

**メモ:** 最近のバージョンの WebRTC adapter.js shim には `getDisplayMedia()` の実装が含まれており、画面共有をサポートしているが現在の標準 API を実装していないブラウザーで画面共有を可能にすることができるので便利かもしれません。これは、少なくとも Chrome、Edge、Firefox で動作します。

画面の内容のキャプチャ
-----------

画面の内容をライブの `MediaStream` でキャプチャするには、 `navigator.mediaDevices.getDisplayMedia()` を呼び出すことで開始され、ライブ画面の内容を含むストリームに解決するプロミスが返されます。

### 画面キャプチャの開始: `async`/`await` スタイル

```js
async function startCapture(displayMediaOptions) {
  let captureStream = null;

  try {
    captureStream =
      await navigator.mediaDevices.getDisplayMedia(displayMediaOptions);
  } catch (err) {
    console.error("Error: " + err);
  }
  return captureStream;
}
```

このコードは、上記のように非同期関数と `await` 演算子を使うか、下記のように `Promise` を直接使って記述することができます。

### 画面キャプチャの開始: `Promise` スタイル

```js
function startCapture(displayMediaOptions) {
  return navigator.mediaDevices
    .getDisplayMedia(displayMediaOptions)
    .catch((err) => {
      console.error("Error:" + err);
      return null;
    });
}
```

いずれにせよ、ユーザーエージェントは、共有する画面領域を選択するようユーザーに促すユーザーインタフェースを提示して応答します。これらの `startCapture()` の実装はどちらも、キャプチャされた表示画像を含む `MediaStream` を返します。

必要な画面の種類を指定する方法と、結果として得られるストリームを調整する他の方法については、以下のオプションと制約を参照してください。

### キャプチャする表示面を選択するウィンドウの例

![Chrome のソース面を選ぶウィンドウの画面ショット](/ja/docs/Web/API/Screen_Capture_API/Using_Screen_Capture/chrome-screen-capture-window.png)

そして、キャプチャしたストリーム `captureStream` を、ストリームを入力として受け付けるあらゆるものに使用することができます。以下の例は、ストリームを利用するためのいくつかの方法を示しています。

### 可視、論理表示面

画面キャプチャ API の用語では、**表示面**は、共有のために API によって選択できる任意のコンテンツオブジェクトです。共有面には、ブラウザータブのコンテンツ、完全なウィンドウ、 1 つの面に結合されたアプリケーションのすべてのウィンドウ、およびモニター（または 1 つの面に結合されたモニターのグループ）が含まれます。

表示面には 2 種類あります。**可視表示面**とは、最前面のウィンドウやタブ、あるいは画面全体など、画面上で全体が見える表示面です。

**論理的表示面**とは、他のオブジェクトとある程度重なっていたり、完全に隠れていたり、画面外にあったりして、部分的または完全に隠されているものです。画面キャプチャ API でこれらをどのように処理するかは、さまざまです。一般にブラウザーは、論理的な表示面の隠れた部分をぼかしたり、色やパターンに置き換えたりして、何らかの方法で隠蔽した画像を提供します。これはセキュリティ上の理由から行われるもので、ユーザーが見ることのできないコンテンツには、共有したくないデータが含まれている可能性があるからです。

ユーザーエージェントは，ユーザから許可を得た上で，不明瞭なウィンドウの全コンテンツのキャプチャを許可するかもしれません。この場合，ユーザーエージェントは，ウィンドウの隠された部分の現在の内容を取得することによって，または現在の内容が利用可能でない場合には最も最近表示された内容を提示することによって，隠された内容を含むことができます。

### オプションと制約

`getDisplayMedia()` に渡される制約オブジェクトは、結果のストリームを設定するために使用されるオブジェクトです。

**メモ:** メディア API における制約のほとんどの用途とは異なり、ここでは、ストリーム構成を定義するためにのみ使用され、利用可能な選択肢をフィルタリングするために使用されるわけではありません。

共有画面トラックのプロパティ (en-US)では、 `MediaTrackConstraints` (en-US)、`MediaTrackSupportedConstraints`、`MediaTrackSettings` (en-US) に追加された画面キャプチャストリームの構成に関する制約について参照できます。

キャプチャするコンテンツが選択されるまで、どのような制約も適用されません。制約は、結果のストリームに表示される内容を変更します。

たとえば、動画に `width` (en-US) 制約を指定すると、ユーザーが共有する領域を選択した後に動画を拡大縮小することによって適用されます。ソース自体のサイズに制約を設けるものではありません。

**メモ:** 制約によって、画面共有 API でキャプチャ可能なソースのリストが変更されることは決してありません。このため、ウェブアプリケーションでは、1 つの項目が残るまでソース リストを制限することによって、ユーザーに特定のコンテンツを共有するように強制することはできません。

表示のキャプチャが行われている間、画面共有を行っているマシンは、共有が行われていることをユーザーに認識させるために、何らかのインジケーターを表示します。

**メモ:** プライバシーとセキュリティ上の理由から、画面共有のソースは `enumerateDevices()` を使って列挙することができないようになっています。これに関連して、`getDisplayMedia()` で利用できるソースに変更があった場合も、 `devicechange` イベントは送信されません。

### 共有音声のキャプチャ

`getDisplayMedia()` は、ユーザーの画面（またはその一部）の動画をキャプチャするために最も一般的に使用されています。しかし、ユーザーエージェントは、動画コンテンツと一緒に音声のキャプチャを許可する場合があります。この音声のソースは、選択されたウィンドウ、コンピューター全体のオーディオシステム、またはユーザーのマイク（または上記のすべての組み合わせ）であるかもしれません。

音声の共有が必要なプロジェクトを始める前に、 ブラウザーの互換性 を確認し、互換性を希望するブラウザーがキャプチャした画面ストリームに音声のサポートがあるかどうかを確認してください。

音声を含む画面の共有を要求するには、 `getDisplayMedia()` に渡すオプションは次のようになります。

```js
const gdmOptions = {
  video: true,
  audio: true,
};
```

これにより、ユーザーエージェントが対応する範囲内で、ユーザーが希望するものを自由に選択することができます。これは、 `audio` と `video` のそれぞれに追加の情報を指定することで、さらに改良することができます。

```js
const gdmOptions = {
  video: {
    cursor: "always",
  },
  audio: {
    echoCancellation: true,
    noiseSuppression: true,
    sampleRate: 44100,
  },
};
```

この例では、カーソルは常にキャプチャで表示され、音声トラックはノイズ抑制とエコーキャンセル機能を有効にし、音声のサンプリングレートは 44.1kHz が理想的です。

音声のキャプチャは常にオプションです。ウェブコンテンツが音声と動画の両方を含むストリームを要求した場合でも、返される `MediaStream` は、音声なしの 1 つの動画トラックのみとなる場合があります。

**メモ:** プロパティによっては広く実装されておらず、エンジンで使用されない場合もあります。例えば `cursor` は 対応が限定されています (en-US)。

キャプチャしたストリームの使用
---------------

`promise` が返す `getDisplayMedia()` は、画面または画面領域を含む少なくとも一つの動画ストリームを含み、 `getDisplayMedia()` が呼ばれたときに指定した制約に基づいて調整またはフィルタリングされた `MediaStream` に解決されます。

### 潜在的なリスク

画面共有を取り巻くプライバシーとセキュリティの問題は、通常、それほど深刻ではありませんが、実際に存在します。最も大きな潜在的問題は、ユーザーが共有したくないコンテンツを不注意に共有してしまうことです。

たとえば、ユーザーが自分の画面を共有しているときに、見えている背景のウィンドウにたまたま個人情報が含まれていたり、パスワードマネージャーが共有ストリームに見えていたりすると、プライバシーやセキュリティの侵害が容易に発生します。論理的な表示面をキャプチャする場合、この影響は増幅される可能性があり、ユーザーは見るどころか、全く知らないコンテンツを含んでいる可能性があります。

プライバシーを真剣に考えるユーザーエージェントは、特にそのコンテンツを共有する権限が与えられていない限り、画面上に実際に表示されていないコンテンツを難読化する必要があります。

### 表示コンテンツのキャプチャの許可

キャプチャした画面コンテンツのストリーミングを開始する前に、ユーザーエージェントは共有の要求を確認し、共有するコンテンツを選択するようユーザーに要求します。

例
-

### 単純な画面キャプチャ

この例では、キャプチャした画面領域の内容を、同じページ内の `<video>` 要素にストリーミングしています。

#### JavaScript

この機能を実現するために必要なコードはそれほど多くありません。 `getUserMedia()` を使ってカメラから動画を取り込むことに慣れているなら、 `getDisplayMedia()` は非常に身近に感じることでしょう。

##### セットアップ

まず、アクセスする必要のあるページ上の要素を参照するために、いくつかの定数が設定されます。キャプチャされた画面のコンテンツがストリームされる `<video>`、ログ出力が描かれるボックス、画面イメージのキャプチャをオン/オフする開始/停止ボタンがあります。

オブジェクト `displayMediaOptions` には `getDisplayMedia()` に渡す制約が含まれています。ここでは `cursor` (en-US) プロパティを `always` に設定しており、マウスカーソルを常にキャプチャメディアに含めることを指定しています。

**メモ:** プロパティによっては広く実装されておらず、エンジンで使用されないかもしれません。例えば `cursor` は サポートが限定されています (en-US).

最後に、イベントリスナーを設定して、スタートボタンとストップボタンに対するユーザーのクリックを検出します。

```js
const videoElem = document.getElementById("video");
const logElem = document.getElementById("log");
const startElem = document.getElementById("start");
const stopElem = document.getElementById("stop");

// Options for getDisplayMedia()

var displayMediaOptions = {
  video: {
    cursor: "always",
  },
  audio: false,
};

// Set event listeners for the start and stop buttons
startElem.addEventListener(
  "click",
  function (evt) {
    startCapture();
  },
  false,
);

stopElem.addEventListener(
  "click",
  function (evt) {
    stopCapture();
  },
  false,
);
```

##### 内容のログ出力

エラーやその他の問題のログを簡単に取るために、この例では特定の `console` メソッドをオーバーライドして、そのメッセージを ID が `log` である `<pre>` ブロックに出力しています。

```js
console.log = (msg) => (logElem.innerHTML += `${msg}<br>`);
console.error = (msg) =>
  (logElem.innerHTML += `<span class="error">${msg}</span><br>`);
console.warn = (msg) =>
  (logElem.innerHTML += `<span class="warn">${msg}<span><br>`);
console.info = (msg) =>
  (logElem.innerHTML += `<span class="info">${msg}</span><br>`);
```

これにより、おなじみの `console.log()` や `console.error()` などを使って、ドキュメント内のログボックスに情報を記録することができるようになります。

##### 画面キャプチャの開始

以下の `startCapture()` メソッドは、ユーザーが画面上で選択した領域から内容を取得する `MediaStream` のキャプチャを開始するものです。`startCapture()` は、 "Start Capture" ボタンがクリックされたときに呼び出されます。

```js
async function startCapture() {
  logElem.innerHTML = "";

  try {
    videoElem.srcObject =
      await navigator.mediaDevices.getDisplayMedia(displayMediaOptions);
    dumpOptionsInfo();
  } catch (err) {
    console.error("Error: " + err);
  }
}
```

前回の接続の際に残ったテキストを取り除くためにログの内容をクリアした後、`startCapture()` は `getDisplayMedia()` を呼び出し、そこに `displayMediaOptions` で定義された制約オブジェクトを渡します。jsxref("Operators/await", "await")}} を使用して、次のコード行は `getDisplayMedia()` が返す `promise` が解決するまで実行されません。解決後、プロミスは `MediaStream` を返し、ユーザが選択した画面、ウィンドウ、その他の領域の内容をストリームとして出力します。

このストリームは、返された `MediaStream` を要素の `srcObject` に格納することによって `<video>` 要素に接続されています。

`dumpOptionsInfo()` 関数は、後で見ることになりますが、教育的な目的のために、ストリームに関する情報をログボックスにダンプします。

もし、どれかが失敗したら、 `catch()` 節は、ログボックスにエラーメッセージを出力します。

##### 画面キャプチャの停止

`stopCapture()` メソッドは "Stop Capture" ボタンがクリックされたときに呼び出されます。これは `MediaStream.getTracks()` を用いてトラックリストを取得し、各トラックの `stop()` メソッドを呼び出してストリームを停止させます。それが終わると、 `srcObject` に `null` がセットされ、ストリームが接続されていないことが誰にでも分かるようにします。

```js
function stopCapture(evt) {
  let tracks = videoElem.srcObject.getTracks();

  tracks.forEach((track) => track.stop());
  videoElem.srcObject = null;
}
```

##### 設定情報のダンプ

参考までに、上記の `startCapture()` メソッドは `dumpOptions()` という名前のメソッドを呼び出し、現在のトラック設定と、ストリームが作成されたときに設定された制約を出力します。

```js
function dumpOptionsInfo() {
  const videoTrack = videoElem.srcObject.getVideoTracks()[0];

  console.info("Track settings:");
  console.info(JSON.stringify(videoTrack.getSettings(), null, 2));
  console.info("Track constraints:");
  console.info(JSON.stringify(videoTrack.getConstraints(), null, 2));
}
```

トラックリストは、キャプチャした画面の `MediaStream` で `getVideoTracks()` を呼び出すことで取得します。現在有効な設定は `getSettings()` (en-US) で、設定されている制約は `getConstraints()` (en-US) で取得されます。

#### HTML

HTML は簡単な紹介文から始まり、本題に入ります。

```html
<p>
  This example shows you the contents of the selected part of your display.
  Click the Start Capture button to begin.
</p>

<p>
  <button id="start">Start Capture</button> <button id="stop">
    Stop Capture
  </button>
</p>

<video id="video" autoplay></video>
<br />

<strong>Log:</strong>
<br />
<pre id="log"></pre>
```

HTML の主要な部分は以下の通りです。

1. "Start Capture" と書かれた `<button>` は、クリックされると `startCapture()` 関数を呼び出し、画面コンテンツへのアクセスを要求し、キャプチャを開始します。
2. "Stop Capture" というラベルの付いた 2 番目のボタンがあり、クリックされると `stopCapture()` を呼び出して画面のコンテンツのキャプチャを終了します。
3. キャプチャされた画面の内容がストリームされる `<video>`。
4. `<pre>` ブロック。この中では、インターセプトされた `console` メソッドによってログが記録されます。

#### CSS

この例では、 CSS は完全に外観上のものです。動画には境界線が付けられ、その幅は利用可能な水平方向のスペースのほぼ全体を占めるように設定されています (`width: 98%`)。 `max-width` には `860px` を設定し、動画のサイズに絶対的な上限を設定しています。

`error`、`warn`、`info` クラスは、対応するコンソール出力の種類をスタイル設定するために使用されます。

```css
#video {
  border: 1px solid #999;
  width: 98%;
  max-width: 860px;
}

.error {
  color: red;
}

.warn {
  color: orange;
}

.info {
  color: darkgreen;
}
```

#### 結果

最終的にはこのようになります。ブラウザーが画面キャプチャ API に対応している場合、"Start Capture" をクリックすると、共有する画面、ウィンドウ、タブを選択するためのユーザーエージェントのインターフェイスが表示されます。

セキュリティ
------

機能ポリシーが有効なときに機能させるためには、 `display-capture` 権限が必要です。これは `Feature-Policy` を用いて行うことができます。または、画面キャプチャ API を `<iframe>` 内で使用している場合は、 `<iframe>` 要素の `allow` 属性を使用します。

例えば、 HTTP ヘッダーのこの行は、文書と同じオリジンから読み込まれる埋め込み `<iframe>` 要素の画面キャプチャ API を有効にします。
```

Feature-Policy: display-capture 'self'
```

もし `<iframe>` 内で画面キャプチャを行うのであれば、そのフレームに対してのみ許可を要求することができ、より一般的な許可を要求するよりも明らかに安全です。

```html
<iframe src="https://mycode.example.net/etc" allow="display-capture"> </iframe>
```

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

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

関連情報
----

* 画面キャプチャ API
* メディアキャプチャとストリーム API
* WebRTC で静止画の写真を撮影 (en-US)
* `HTMLCanvasElement.captureStream()` で `<canvas>` のライブコンテンツの `MediaStream` を取得できる


OrientationSensor: populateMatrix() メソッド - Web API

OrientationSensor: populateMatrix() メソッド
========================================

`OrientationSensor` インターフェイスの **`populateMatrix`** メソッドは、指定の書き込み先行列に、センサーの最新の測定値に基づく回転行列を入れます。回転行列は以下のものです。

![センサーの四元数を行列に変換するのに用いられる数式](/ja/docs/Web/API/OrientationSensor/populateMatrix/quaternion_to_rotation_matrix.png)

ただし:

* W = cos(θ/2)
* X = Vx \* sin(θ/2)
* Y = Vy \* sin(θ/2)
* Z = Vz \* sin(θ/2)
構文
--

```js
populateMatrix(targetMatrix)
```

`OrientationSensor` はベースクラスなので、`populateMatrix` は派生クラスからのみ読み取ることができます。

### 引数

`targetMatrix`

TBD

### 返値

なし (`undefined`)

例
-

```js
// TBD
```

仕様書
---

| Specification |
| --- |
| Orientation Sensor # orientationsensor-populatematrix |

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

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


OrientationSensor: quaternion プロパティ - Web API

OrientationSensor: quaternion プロパティ
===================================

`OrientationSensor` インターフェイスの読み取り専用プロパティ **`quaternion`** は、各要素がデバイスの向きを表す単位四元数の成分である 4 要素の `Array` を返します。

`OrientationSensor` はベースクラスなので、`quaternion` は派生クラスからのみ読み取ることができます。

値
-

デバイスの向きを表す四元数の x, y, z, w 成分を値とする `Array` です。

例
-

```js
// TBD
```

仕様書
---

| Specification |
| --- |
| Orientation Sensor # orientationsensor-quaternion |

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

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


PushMessageData: blob() メソッド - Web API

PushMessageData: blob() メソッド
============================

**`blob()`** は `PushMessageData` インターフェイスのメソッドで、プッシュメッセージデータを `Blob` オブジェクトとして抽出します。

構文
--

```js
blob()
```

### 引数

なし。

### 返値

`Blob` です。

例
-

```js
self.addEventListener("push", (event) => {
  const blob = event.data.blob();

  // Blob を使用して何かを実行する。
});
```

仕様書
---

| Specification |
| --- |
| Push API # dom-pushmessagedata-blob |

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

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


PushMessageData: text() メソッド - Web API

PushMessageData: text() メソッド
============================

**`text()`** は `PushMessageData` インターフェイスのメソッドで、プッシュメッセージのデータをプレーンテキスト文字列として抽出します。

構文
--

```js
text()
```

### 引数

なし。

### 返値

文字列です。

例
-

```js
self.addEventListener("push", (event) => {
  const textObj = event.data.text();

  // テキストを使用して何かを実行する
});
```

仕様書
---

| Specification |
| --- |
| Push API # dom-pushmessagedata-text |

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

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


PushMessageData: json() メソッド - Web API

PushMessageData: json() メソッド
============================

**`json()`** は `PushMessageData` インターフェイスのメソッドで、プッシュメッセージのデータを JSON 文字列として解釈し、結果を返します。

構文
--

```js
json()
```

### 引数

なし。

### 返値

プッシュイベントのデータを JSON として解釈した結果です。これは JSON で表現されるあらゆるものになり得ます。オブジェクト、配列、文字列、数値などです。

例
-

```js
self.addEventListener("push", (event) => {
  const myData = event.data.json();

  // JSON を使って何かを実行する
});
```

仕様書
---

| Specification |
| --- |
| Push API # dom-pushmessagedata-json |

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

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


PushMessageData: arrayBuffer() メソッド - Web API

PushMessageData: arrayBuffer() メソッド
===================================

**`arrayBuffer()`** は `PushMessageData` インターフェイスのメソッドで、プッシュメッセージデータを `ArrayBuffer` オブジェクトとして抽出します。

構文
--

```js
arrayBuffer()
```

### 引数

なし。

### 返値

`ArrayBuffer` です。

例
-

```js
self.addEventListener("push", (event) => {
  const buffer = event.data.arrayBuffer();

  // 配列バッファーを使用して何かを実行する。
});
```

仕様書
---

| Specification |
| --- |
| Push API # dom-pushmessagedata-arraybuffer |

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

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


Permissions API の使用 - Web API

Permissions API の使用
===================

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

この記事では、W3C の Permissions API を使用するための基本的なガイドを提供します。 これは、現在のコンテキストに起因する API のパーミッションの状態を照会するためのプログラムによる方法を提供します。

パーミッションを求めるのが面倒
---------------

ウェブ上のパーミッションは必要悪であり、そしてそれらは開発者として対処するのはそれほど面白くありませんが、それに立ち向かいましょう。

歴史的には、異なる API は独自のパーミッションを一貫性のない方法で扱います。 例えば、Notifications API はパーミッションの状態の明示的なチェックとパーミッションの要求を許可しますが、Geolocation API はそうではありません（以下に示すように、ユーザーが最初のパーミッションの要求を拒否すると問題を引き起こします）。

Permissions API は、パーミッションに関する限り、開発者がより良いユーザーエクスペリエンスを実装できるようにするためのツールを提供します。 例えば、特定の API を使用するためのパーミッションが付与されているか拒否されているかを照会し、API を使用するためのパーミッションを具体的に要求することができます。

現時点では、API の実装は初期段階にあるため、ブラウザーでのサポートは次のようにかなりむらがあります。

* Chrome 44 以降と Firefox 43 以降でしか見つかりません。
* 現在サポートしている唯一のメソッドは `Permissions.query()` で、これはパーミッションの状態を問い合わせます。
* Chrome の Permissions API が現在認識している API は、Geolocation と Notification の 2 つだけです。 Firefox は Push と WebMIDI も認識します。

時間が経つにつれて、より多くの機能が追加されます。

簡単な例
----

この記事では、Location Finder という簡単なデモをまとめました。 Geolocation を使用してユーザーの現在地を照会し、それをグーグルマップに表示します。

![英国 Greenfield の地図を表示したスクリーンショット。](/ja/docs/Web/API/Permissions_API/Using_the_Permissions_API/location-finder-with-permissions-api.png)

サンプルをライブで実行するか、Github でソースコードを見ることができます。 コードの大部分は単純で目立たないものです。 以下では Permissions API 関連のコードを見ていきますので、他の部分を調べたい場合はコードを自分で確認してください。

### Permissions API へのアクセス

グローバルな `Permissions` オブジェクトへのアクセスを許可するために、`Navigator.permissions` プロパティがブラウザーに追加されました。 現在、このオブジェクトには `Permissions.query()` しか含まれていませんが、最終的にはパーミッションの照会、要求、および取り消しのためのメソッドが含まれます。 下記参照。

### パーミッションの状態の照会

この例では、Permissions 機能は `handlePermission()` という 1 つの関数によって処理されます。 これは、`Permissions.query()` を使用してパーミッションの状態を照会することから始まります。 Promise が解決されたときに返される `PermissionStatus` オブジェクトの `state` プロパティの値に応じて、次のように反応は異なります。

`"granted"`（付与）

[Geolocation を有効にする（Enable Geolocation）] ボタンは非表示です。 これは、Geolocation がすでにアクティブになっている場合は必要ないためです。

`"prompt"`（プロンプト）

[Geolocation を有効にする] ボタンは非表示です。 これは、ユーザーに Geolocation のパーミッションを付与するように求めるプロンプトが表示される場合は必要ないためです。 `Geolocation.getCurrentPosition()` 関数を実行し、ユーザーにパーミッションを求めるプロンプトを表示します。 それは、パーミッションが付与されている場合、`revealPosition()` 関数を実行し（地図を表示します）、パーミッションが拒否されている場合、`positionDenied()` 関数を実行します（[Geolocation を有効にする] ボタンを表示します）。

`"denied"`（拒否）

[Geolocation を有効にする] ボタンを表示します（ページが最初に読み込まれたときに、パーミッションの状態がこのオリジンに対して既に拒否に設定されている場合も、このコードにくる必要があります）。

```js
function handlePermission() {
  navigator.permissions.query({ name: "geolocation" }).then(function (result) {
    if (result.state == "granted") {
      report(result.state);
      geoBtn.style.display = "none";
    } else if (result.state == "prompt") {
      report(result.state);
      geoBtn.style.display = "none";
      navigator.geolocation.getCurrentPosition(
        revealPosition,
        positionDenied,
        geoSettings,
      );
    } else if (result.state == "denied") {
      report(result.state);
      geoBtn.style.display = "inline";
    }
    result.onchange = function () {
      report(result.state);
    };
  });
}

function report(state) {
  console.log("Permission " + state);
}

handlePermission();
```

### パーミッション記述子

`Permissions.query()` メソッドはパラメータとして `PermissionDescriptor` ディクショナリを取ります — これはあなたが興味を持っている API の名前を含みます。 いくつかの API は、デフォルトの `PermissionDescriptor` から継承した、追加情報を含んだ、より複雑な `PermissionDescriptor` を持っています。 例えば、`PushPermissionDescriptor` には、`userVisibleOnly` が `true` か `false` かを指定する Boolean も含める必要があります。

### パーミッションの取り消し

Firefox 47 以降、`Permissions.revoke()` メソッドを使用して既存のパーミッションを取り消すことができるようになりました。 これは `Permissions.query()` メソッドとまったく同じように機能しますが、Promise が正常に解決されると、既存のパーミッションがデフォルトの状態（通常は `prompt`）に戻される点が異なります。 デモで次のコードを見てください。

```js
var revokeBtn = document.querySelector('.revoke');

  ...

revokeBtn.onclick = function() {
  revokePermission();
}

  ...

function revokePermission() {
  navigator.permissions.revoke({name:'geolocation'}).then(function(result) {
    report(result.state);
  });
}
```

**メモ:** Firefox 51 以降、Web Applications Security Working Group で設計が問題になっているため、`revoke()` 関数はデフォルトで無効になっています。 設定 `dom.permissions.revoke.enable` を `true` に設定することで再度有効にすることができます。

### パーミッションの状態の変更への対応

上記のコードには、`PermissionStatus` オブジェクトにアタッチされた `onchange` イベントハンドラがあることに気付くでしょう。 これにより、関心のある API のパーミッションの状態の変更に対応できるようになります。 現時点では、状態の変化を報告しているだけです。

まとめと今後の課題
---------

現時点では、これは私たちがすでに持っていたもの以上のものを提供するものではありません。 パーミッションのプロンプトから位置を決して共有しないことを選択した場合（パーミッションを拒否した場合）、ブラウザーのメニューオプションを使用しないとパーミッションのプロンプトに戻ることはできません。

* **Firefox**: [ツール] > [ページの情報] > [サイト別設定] の順にクリックします。 [位置情報の送信] で [標準設定を使用する] をチェックします。
* **Chrome**: [ハンバーガーメニュー] > [設定] > [詳細設定] の順にクリックします。 [プライバシーとセキュリティ] セクションで [サイトの設定] をクリックします。 表示されたダイアログで、[位置情報] セクションを探し、[アクセスする前に確認する] を選択します。 最後に、[すべてのサイトに保存されている権限とデータを表示する] をクリックして、関心のあるサイトに付与されているパーミッションを削除します。

しかしながら、ブラウザー機能への将来の追加は `request()` メソッドを提供するべきです、それは私たちが好きなときにいつでもプログラム的にパーミッションを要求することを可能にするでしょう。 うまくいけばこれらはすぐに利用可能になるはずです。


Image() - Web API

Image()
=======

**`Image()`** コンストラクターは、新しい `HTMLImageElement` インスタンスを作成します。機能的には `document.createElement('img')` と同等です。

**メモ:** この関数を CSS の `image()` 関数と混同しないでください。

構文
--

```js
new Image();
new Image(width);
new Image(width, height);
```

### 引数

`width` 省略可

画像の幅（つまり `width` 属性に対応する値）です。

`height` 省略可

画像の高さ（つまり `height` 属性に対応する値）です。

使用上の注意
------

ビットマップ全体は、コンストラクターで指定されたサイズに関係なく読み込まれます。コンストラクターで指定されたサイズは、結果のインスタンスのプロパティ `HTMLImageElement.width` と `HTMLImageElement.height` を通して反映されます。画像の本来の幅と高さは CSS ピクセルで表され、プロパティ `HTMLImageElement.naturalWidth` と `HTMLImageElement.naturalHeight` を通して反映されます。コンストラクターでサイズが指定されていない場合、両プロパティのペアは同じ値を持ちます。

例
-

```js
var myImage = new Image(100, 200);
myImage.src = "picture.jpg";
document.body.appendChild(myImage);
```

これは、 `<body>` の中で次のような HTML タグを定義するのと同じです。

```html
<img width="100" height="200" src="picture.jpg" />
```

仕様書
---

| Specification |
| --- |
| HTML Standard # dom-image-dev |

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

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


HTMLImageElement: fetchPriority プロパティ - Web API

HTMLImageElement: fetchPriority プロパティ
=====================================

Limited availability
--------------------

This feature is not Baseline because it does not work in some of the most widely-used browsers.

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

**`fetchPriority`** は `HTMLImageElement` インターフェイスのプロパティで、ブラウザーが他の画像と比較して、画像の取得をどのように優先させるべきかというヒントを表します。

値
-

優先度ヒントを表す文字列です。使用可能な値は以下の通りです。

`high`

他の画像と比較して高い優先度で画像を取得します。

`low`

他の画像と比較して低い優先度で画像を取得します。

`auto`

既定のモード。取得の優先順位がないことを示します。ユーザーにとって最適なものをブラウザーが決定します。

`fetchPriority` プロパティを使用すると、画像の取得の優先順位を高くしたり低くしたりすることができます。これは `<img>` 要素に適用すると、読み込み処理の早い段階でユーザの操作にとって「重要」な画像を通知するのに役立ちます。

リソースの読み込みに対するヒントの効果はブラウザーに依存するため、複数のブラウザーエンジンで試すようにしてください。

ブラウザーが画像を自動的に読み込むための最適な方法を推測できないような例外的なケースには、控えめに使用するようにしてください。過剰に使用すると、パフォーマンスが低下する可能性があります。

例
-

```js
const img = new Image();
img.fetchPriority = "high";
img.src = "img/logo.png";
```

仕様書
---

| Specification |
| --- |
| HTML Standard # attr-img-fetchpriority |

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

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


HTMLImageElement: height プロパティ - Web API

HTMLImageElement: height プロパティ
==============================

**`height`** は `HTMLImageElement` インターフェイスのプロパティで、画像が画面やプリンターなどの視覚媒体に描画または表示される場合は CSS ピクセルで、それ以外は画像のピクセル密度補正後の高さを表します。

値
-

画像の高さを表す整数値です。高さがどのように定義されるかは、画像が視覚的媒体にレンダリングされるかどうかに依存します。

* 画像が画面やプリンターなどの視覚媒体にレンダリングされる場合、高さは CSS ピクセルで表現されます。
* それ以外の場合、画像の高さは、 `naturalHeight` で示される表示密度用に調整された自然の（固有の）高さで表わされます。
例
-

この例では、 `srcset` 属性を使って、時計の画像に 2 種類の大きさの画像を用意しています。ひとつは幅 200px、もうひとつは幅 400px です。さらに、 `sizes` 属性は、ビューポートの幅を考慮して画像を描画する幅を指定するために提供されています。

### HTML

 具体的には、幅 400px までのビューポートでは、 200px の幅で描画されます。
 それ以外の場合は、 300px で描画されます。

```html
<p>画像の高さ: <span class="size">?</span>px (リサイズで更新)</p>
<img
 src="/en-US/docs/Web/HTML/Element/img/clock-demo-200px.png"
 alt="Clock"
 srcset="
 /en-US/docs/Web/HTML/Element/img/clock-demo-200px.png 200w,
 /en-US/docs/Web/HTML/Element/img/clock-demo-400px.png 400w
 "
 sizes="(max-width: 400px) 200px, 300px" />
```

### JavaScript

JavaScript のコードでは `height` を見て、現在描画されている幅から画像の高さを決定しています。

```js
const clockImage = document.querySelector("img");
let output = document.querySelector(".size");

const updateHeight = (event) => {
  output.innerText = clockImage.height;
};

window.addEventListener("load", updateHeight);
window.addEventListener("resize", updateHeight);
```

### 結果

この例は独自のウィンドウで試してみるとわかりやすいかもしれません。

仕様書
---

| Specification |
| --- |
| HTML Standard # dom-img-height-dev |

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

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


HTMLImageElement: decode() メソッド - Web API

HTMLImageElement: decode() メソッド
===============================

**`decode()`** は `HTMLImageElement` インターフェイスのメソッドで、画像がデコードされ、 DOM に画像を追加しても安全になったときに解決されるプロミス (`Promise`) を返します。

これは、画像を DOM 内の要素に装着する（または新しい要素として DOM に追加する）前に画像の読み込みを開始し、 DOM に追加された時点ですぐに画像をレンダリングできるようにするために使用します。これにより、DOM に画像を追加した後の次のフレームのレンダリングで、画像の読み込み中に遅延が発生するのを防ぐことができます。

構文
--

```js
decode()
```

### 引数

なし。

### 返値

画像データが利用できるようになったときに解決される `Promise` です。

### 例外

`EncodingError`

画像のデコード中にエラーが発生したことを示す `DOMException` です。

使用上の注意
------

`decode()` の潜在的な使用例の一つです。非常に大きな画像を読み込む場合（例えばオンラインのフォトアルバムで）、最初は低解像度のサムネイル画像を表示し、その後、新しい `HTMLImageElement` をインスタンス化してそのソースにフル解像度画像の URL を設定し、`decode()` を使ってプロミスを取得し、フル解像度画像が使えるようになったときに解決することによって、画像をフル解像度画像と交換することが可能です。その際、低解像度の画像を、現在利用可能なフル解像度の画像に置き換えることができます。

例
-

次の例では、 `decode()` メソッドを使って、画像が DOM に追加されるタイミングを制御しています。 `Promise` を返すメソッドがなければ、 `load` イベントハンドラーで画像を DOM に追加し、 `img.onload` イベントのハンドラでエラーを処理するなどの方法で、画像を追加することになります。

```js
const img = new Image();
img.src = "nebula.jpg";
img
  .decode()
  .then(() => {
    document.body.appendChild(img);
  })
  .catch((encodingError) => {
    // エラー時に何かをする。
  });
```

仕様書
---

| Specification |
| --- |
| HTML Standard # dom-img-decode-dev |

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

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


HTMLImageElement: vspace プロパティ - Web API

HTMLImageElement: vspace プロパティ
==============================

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

**`vspace`** は `HTMLImageElement` インターフェイスの廃止されたプロパティで、ページをレイアウトする際に `<img>` 要素の上下に空ける空間のピクセル数を指定します。

値
-

画像の上下に適用される垂直方向のマージンの高さをピクセル単位で指定する整数値。

使用上の注意
------

`vspace` に指定された値は `margin-top` と `margin-bottom` プロパティに対応付けられ、それらのマージンの高さをピクセル単位で指定します。

**警告:** このプロパティは廃止されています。代わりに、 CSS の `margin` プロパティとその個別指定形を使用して、`<img>` の周囲にマージンを設定してください。

仕様書
---

| Specification |
| --- |
| HTML Standard # dom-img-vspace |

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

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


HTMLImageElement: useMap プロパティ - Web API

HTMLImageElement: useMap プロパティ
==============================

**`useMap`** は `HTMLImageElement` インターフェイスのプロパティで、 HTML の `usemap` 属性を反映し、この画像に適用されるクライアントサイドイメージマップの名前を提供する文字列です。

値
-

画像に適用するイメージマップを定義する `<map>` 要素のページローカル URL (つまり、ハッシュまたはポンド記号 "`#`" で始まる URL) を指定する文字列です。

クライアントサイドのイメージマップについては、学習記事「画像の上にヒットマップを追加する」で詳しく説明されています。

使用上の注意
------

`useMap` の文字列値は `<map>` 要素の有効なアンカーでなければなりません。言い換えると、この文字列は適切な `<map>` の `name` 属性の値の前に、ポンド記号またはハッシュ記号を付加したものでなければなりません。

次のような `<map>` を考えてみましょう。

```html
<map name="mainmenu-map">
  <area
 shape="circle"
 coords="25, 25, 75"
 href="/index.html"
 alt="Return to home page" />
  <area shape="rect" coords="25, 25, 100, 150" href="/index.html" alt="Shop" />
</map>
```

`mainmenu-map` という名前のイメージマップがあるとすると、それを使ったイメージは以下のようなものになります。

```html
<img src="menubox.png" usemap="#mainmenu-map" />
```

他の例（インタラクティブなものもあります）については、 `<map>` と `<area>` 要素についての記事や、イメージマップの使用法をご覧下さい。

例
-

試してみましょう
--------

仕様書
---

| Specification |
| --- |
| HTML Standard # dom-img-usemap |

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

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


HTMLImageElement: alt プロパティ - Web API

HTMLImageElement: alt プロパティ
===========================

`HTMLImageElement` の **`alt`** プロパティは、`<img>` 要素で指定された画像が読み込まれない場合に表示する予備（代替）テキストを指定します。

画像が読み込まれないのは、エラーが発生した場合、ユーザーが画像の読み込みを無効にしている場合、または画像の読み込みがまだ終了していない場合があります。

 おそらく `alt` プロパティを使用する最も重要な理由は、アクセシビリティに対応することです。なぜなら `alt` テキストはスクリーンリーダーや他の支援技術によって使用され、障碍のあるユーザーがコンテンツを十分に活用できるようサポートするからです。
 例えば、視覚障碍のあるユーザーをサポートするために、音声で読み上げたり、タッチ端末に送ったりします。

>
> **このように考えてください。** 画像の `alt` 文字列を選ぶときは、ページ上に画像があることに触れずに、電話で誰かにページを読み聞かせるときのことを想像してみてください。
>
>
>

代替テキストは、画像が占めるであろう空間に表示され、*ページの意味を変えることなく*画像の代わりをすることができるはずです。

値
-

画像が読み込まれない場合、または支援装置で使用するために表示する代替テキストを含む文字列です。

`alt` 属性は公式には必須です。常に指定するように意図されています。
 画像が予備を必要としない場合（例えば、装飾的な画像や重要性の低いアイコンの場合）、空文字列 (`""`) を指定することができます。
 互換性の理由から、ブラウザーは一般的に `alt` 属性なしの画像を受け入れますが、それを使う習慣を身につけるようにしましょう。

使用上の注意
------

`alt` 属性の基本的なガイドラインは、すべての画像の代替テキストは、*ページの意味を変えることなく*画像を置き換えることができるものであるべきであるということです。キャプションやタイトルとして解釈される可能性のあるテキストには、決して `alt` を使用すべきではありません。
 そのような目的のために設計された別の属性や要素があります。

例
-

 それ以外にも、 `alt` を適切に使用するためのガイドラインがあり、画像が何に使用されるかに応じて異なります。
 これらは以下の例で示されています。

### 装飾的な画像

 装飾的なイメージや限られた情報価値しかないイメージなど、意味を持たないイメージは `alt` 属性に空の文字列 (`""`) を設定する必要があります。
 これは以下の例で示されています。

#### HTML

以下に示すこの例の HTML では、`<img>` 要素に `alt` プロパティが含まれており、画像は装飾なので代替テキストを持つことができないようになっています。

```html
<div class="container">
  <div class="left-margin">
    <img src="/files/16861/margin-flourish.svg" alt="" />
  </div>
  <div class="contents">
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque quis orci
      ligula. Lorem ipsum dolor sit amet, consectetur adipiscing elit. In ac
      neque libero. Vivamus consectetur rhoncus elit eget porta. Etiam pulvinar
      ex id sapien laoreet, quis aliquet odio lobortis. Nam ac mauris at risus
      laoreet cursus vitae et sapien. Etiam molestie auctor eros, ac porta risus
      scelerisque sit amet. Ut nunc neque, porta eu auctor at, tempor et arcu.
    </p>
  </div>
</div>
```

#### CSS

この例の CSS は、以下の結果に示すように、レイアウトのスタイルを設定する。

```css
body {
  margin: 0;
  padding: 0;
}

p {
  margin-block-start: 0;
  margin-block-end: 1em;
  margin-top: 0;
  margin-bottom: 1em;
}

.container {
  width: 100vh;
  height: 95vh;
  font:
    16px Arial,
    Helvetica,
    sans-serif;
}

.left-margin {
  background-color: rgb(241, 240, 237);
  width: 9em;
  height: 100%;
  float: left;
  margin-right: 5px;
  padding-right: 1em;
  display: flex;
  align-items: center;
  justify-content: center;
}

.left-margin img {
  width: 6em;
}

.contents {
  background-color: rgb(241, 240, 235);
  height: 100%;
  margin-left: 2em;
  padding-top: 1em;
  padding-left: 2em;
  padding-right: 1em;
}
```

#### 結果

### ボタンとして使われる画像

 画像をボタンとして使う場合（ハイパーリンクを表す `<a>` 要素の唯一の可視の子として使う）、ボタンの目的を伝えるために `alt` 属性を使用しなければなりません。
 言い換えれば、同じ目的を果たすためにテキストボタンで使用するのと同じテキストでなければなりません。

例えば、以下の HTML のスニペットでは、アイコン画像をリンクラベルとして使用するツールバーで、アイコンを使用できない場合や意図的に使用しない場合にアイコンの代わりに使用するテキストラベルを与えるために、それぞれ `alt` 属性を提供しています。

```html
<li class="toolbar" aria-role="toolbar">
  <a href="songs.html" aria-role="button">
    <img src="songicon.svg" alt="Songs" />
  </a>
  <a href="albums.html" aria-role="button">
    <img src="albumicon.svg" alt="Albums"
 /></a>
  <a href="artists.html" aria-role="button">
    <img src="artisticon.svg" alt="Artists" />
  </a>
  <a href="playlists.html" aria-role="button">
    <img src="playlisticon.svg" alt="Playlists" />
  </a>
</li>
```

### 図や地図を含む画像

 画像が概念図、グラフ、図、マップとして表示される情報を含んでいる場合、`alt` テキストは少なくとも要約した形で同じ情報を提供する必要があります。
 これは /me の画像が PNG のようなビットマップ形式であっても JPEG や SVG などのベクター形式で提供されます。

* 地図の場合、 `alt` のテキストは地図で示された場所への道順を、口頭で説明するのと同じように説明することができます。
* グラフの場合、テキストはそのグラフの項目とその値を説明することができます。
* 概念図の場合、テキストはその概念図で示される概念の説明になります。

SVG 形式で表示される概念図やグラフに含まれるテキストは、スクリーンリーダーで読み取られる可能性があることに留意してください。
 このことは、図の `alt` テキストを記述する際の判断に影響を与えるかもしれません。

### アイコンやロゴ

 ロゴ（企業やブランドのロゴなど）や情報アイコンには、対応するテキストを `alt` 文字列として使用する必要があります。
 つまり、画像が企業ロゴの場合、 `alt` テキストはその企業名であるべきです。
 画像が状態やその他の情報を表すアイコンの場合、テキストはその状態の名前であるべきです。

例えば、画像がページのコンテンツが新しく、最近更新されたことを示すためにページに表示されるバッジの場合、対応する `alt` テキストは "`最近更新`" または "`2019 年 8 月 27 日更新`" のようになるかもしれません。

 この例では、 "New!" という文字の入った星形の画像を使って、記事が何か新しいもの（そしておそらくは刺激的なもの）についてのものであることを表しています。
 画像がない場合に画像の代わりにそのテキストを表示できるように、 `alt`属性に `New Page!` が設定されています。
 また、スクリーンリーダーで読み取ることも可能です。

#### HTML

 以下の HTML は、説明したアイコンを使用したサイトのコンテンツのスニペットを作成します。
 なお、`<img>` で `alt` 属性を使用することで、画像が読み込まれなかった場合に使用される良い代替文字列を提供します。

```html
<div class="container">
  <img
 src="https://www.bitstampede.com/mdn-test/new-page.svg"
 alt="New Page!"
 class="pageinfo-badge" />
  <p class="contents">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque quis orci
    ligula. Lorem ipsum dolor sit amet, consectetur adipiscing elit. In ac neque
    libero. Vivamus consectetur rhoncus elit eget porta. Etiam pulvinar ex id
    sapien laoreet, quis aliquet odio lobortis. Nam ac mauris at risus laoreet
    cursus vitae et sapien. Etiam molestie auctor eros, ac porta risus
    scelerisque sit amet. Ut nunc neque, porta eu auctor at, tempor et arcu.
  </p>
</div>
```

#### CSS

ここでの CSS の最大の特徴は、 `clip-path` と `shape-outside` を使って、アイコンにテキストを魅力的に巻き込んでいることです。

```css
.container {
  max-width: 500px;
}

.pageinfo-badge {
  width: 9em;
  padding-right: 1em;
  float: left;
  clip-path: polygon(
    100% 0,
    100% 50%,
    90% 70%,
    80% 80%,
    70% 90%,
    50% 100%,
    0 100%,
    0 0
  );
  shape-outside: polygon(
    100% 0,
    100% 50%,
    90% 70%,
    80% 80%,
    70% 90%,
    50% 100%,
    0 100%,
    0 0
  );
}

.contents {
  margin-top: 1em;
  font:
    16px Arial,
    Helvetica,
    Verdana,
    sans-serif;
}
```

#### 結果

### その他の画像

 オブジェクトやシーンを示す画像には、画像に写っているものを説明する `alt` テキストが必要です。
 例えば、黄色いティーポットの写真は、文字どおり `alt` 属性に "`黄色いティーポット`" と設定することができます。

仕様書
---

| Specification |
| --- |
| HTML Standard # dom-img-alt |

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

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


HTMLImageElement: crossOrigin プロパティ - Web API

HTMLImageElement: crossOrigin プロパティ
===================================

`HTMLImageElement` インターフェイスの **`crossOrigin`** 属性は、画像を取得する際に使用するオリジン間リソース共有 (CORS) 設定を指定するための文字列です。

値
-

画像リソースを取得する際に使用する CORS モードを指定するキーワードの文字列です。 `crossOrigin` を指定しない場合、画像は CORS なしで取得されます（`no-cors` フェッチモード）。

許可されている値は次の通りです。

`anonymous`

`<img>` 要素によるリクエストは、`mode` が `cors` に、`credentials` モードが `same-origin` に設定されて行われます。これは、CORS が有効であり、文書が読み込まれたのと同じオリジンから画像が取得された場合に、クレデンシャルが送信されることを意味します。

`use-credentials`

`HTMLImageElement` によるリクエストは `cors` モードと `include` 認証モードを使用します。この要素によるすべての画像リクエストは、取得元のドメインに関係なく CORS を使用します。

`crossOrigin` が空の文字列 (`""`) の場合、`anonymous` モードが選択されます。

例
-

この例では、新しい `<img>` 要素が作成されて文書に追加され、匿名状態の画像が読み込まれます。画像は CORS を使用して読み込まれ、資格情報がオリジンをまたいだすべての読み込みに使用されます。

### JavaScript

以下のコードでは、 `<img>` 要素に `crossOrigin` プロパティを設定して、新しく作成された画像のフェッチに対する CORS アクセスを設定する例を示しています。

```js
const imageUrl = "clock-demo-400px.png";
const container = document.querySelector(".container");

function loadImage(url) {
  const image = new Image(200, 200);
  image.addEventListener("load", () => container.prepend(image));

  image.addEventListener("error", () => {
    const errMsg = document.createElement("output");
    errMsg.value = `Error loading image at ${url}`;
    container.append(errMsg);
  });

  image.crossOrigin = "anonymous";
  image.alt = "";
  image.src = url;
}

loadImage(imageUrl);
```

### HTML

```html
<div class="container">
  <p>
    ここに 1 つの段落があります。とても面白い段落です。
    あなたはこの段落に魅了されています。 この段落を読み続けてください。
    じゃあ、もうこの段落を読むのはやめていいよ。 読んでくれてありがとう。
  </p>
</div>
```

### CSS

```css
body {
  font:
    1.125rem/1.5,
    Helvetica,
    sans-serif;
}

.container {
  display: flow-root;
  width: 37.5em;
  border: 1px solid #d2d2d2;
}

img {
  float: left;
  padding-right: 1.5em;
}

output {
  background: rgba(100, 100, 100, 0.1);
  font-family: Courier, monospace;
  width: 95%;
}
```

### 結果

仕様書
---

| Specification |
| --- |
| HTML Standard # dom-img-crossorigin |

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

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


HTMLImageElement: sizes プロパティ - Web API

HTMLImageElement: sizes プロパティ
=============================

`HTMLImageElement` の **`sizes`** プロパティによって、メディア条件のリストごとに、画像のレイアウト幅を指定することができます。これにより、様々なメディア条件に合わせて文書の状態が変化したときに、異なる画像（方向やアスペクト比の異なる画像も含む）を自動的に選択する機能が提供されます。

それぞれの条件は、メディアクエリーで使われているのと同じ条件指定の形式を使用します。

値
-

カンマで区切られたソースサイズ記述子のリストと、オプションで代替サイズを含む文字列。それぞれの**ソースサイズ記述子**は、メディア条件、 1 つ以上のホワイトスペース文字、そしてメディア条件が `true` と評価されたときに画像に使用する**ソースサイズ値**で構成されます。

### メディア条件

それぞれのソースサイズ記述子は、メディアクエリー規格で定義されるメディア条件から構成される。ソースサイズ記述子は、ページのレイアウト中に画像に使用する幅を指定するために使用されるので、メディア条件は通常、幅の情報のみに基づきます（必ずしもそうとは限りません）。メディア条件の構築方法の詳細は、メディアクエリーの使用の構文を参照してください。

### ソースサイズ値

ソースサイズの値は CSS の長さです。フォントと相対的な単位 (`em` や `ex` など)、絶対的な単位 (`px` や `cm` など)、または `vw` という単位を使って指定することができ、ビューポート幅に対する割合（`1vw` はビューポート幅の 1%）で指定することができます。

**メモ:** ソースサイズ値は、コンテナーサイズに対するパーセント値として指定してはいけません。つまり、`50%` や `100%` といった長さの指定は、指定した値が何に対するパーセント値であるかが不明確になるため、許されません。

例
-

### ウィンドウの幅に合う画像の選択

この例では、ブログ風のレイアウトを作成し、テキストと画像を表示します。画像は、ウィンドウの幅に応じて 3 つのサイズポイントが指定されています。画像も 3 種類用意し、それぞれの幅を指定しています。ブラウザーはこれらの情報をすべて受け取り、指定された値に最も合う画像と幅を選択します。

画像がどのように使われるかは、ブラウザーやユーザーのディスプレイの画素密度に依存する場合があります。

この例の下にあるボタンで、実際に `sizes` プロパティを少し変更し、画像の 3 つの幅のうち最大のものを 40em と 50em の間で切り替えています。

#### HTML

```html
<article>
  <h1>An amazing headline</h1>
  <div class="test"></div>
  <p>
    This is even more amazing content text. It's really spectacular. And
    fascinating. Oh, it's also clever and witty. Award-winning stuff, I'm sure.
  </p>
  <img
 src="new-york-skyline-wide.jpg"
 srcset="
 new-york-skyline-wide.jpg 3724w,
 new-york-skyline-4by3.jpg 1961w,
 new-york-skyline-tall.jpg 1060w
 "
 sizes="((min-width: 50em) and (max-width: 60em)) 50em,
 ((min-width: 30em) and (max-width: 50em)) 30em,
 (max-width: 30em) 20em"
 alt="The New York City skyline on a beautiful day, with the One World Trade Center building in the middle." />
  <p>
    Then there's even more amazing stuff to say down here. Can you believe it? I
    sure can't.
  </p>

  <button id="break40">Last Width: 40em</button>
  <button id="break50">Last Width: 50em</button>
</article>
```

### CSS

```css
article {
  margin: 1em;
  max-width: 60em;
  min-width: 20em;
  border: 4em solid #880e4f;
  border-radius: 7em;
  padding: 1.5em;
  font:
    16px "Open Sans",
    Verdana,
    Arial,
    Helvetica,
    sans-serif;
}

article img {
  display: block;
  max-width: 100%;
  border: 1px solid #888;
  box-shadow: 0 0.5em 0.3em #888;
  margin-bottom: 1.25em;
}
```

### JavaScript

JavaScript のコードでは、　3　つ目の幅のオプションを 40em と 50em の間で切り替えることができる　2　つのボタンを処理しています。これは `click` イベントを処理することで、 JavaScript 文字列オブジェクトメソッド `replace()`を使って `sizes` 文字列の該当部分を置換して実現しています。

```js
const image = document.querySelector("article img");
const break40 = document.getElementById("break40");
const break50 = document.getElementById("break50");

break40.addEventListener(
  "click",
  () => (image.sizes = image.sizes.replace(/50em,/, "40em,")),
);

break50.addEventListener(
  "click",
  () => (image.sizes = image.sizes.replace(/40em,/, "50em,")),
);
```

### 結果

このページは独自のウィンドウで見るほうが、大きさを完全に調整できるので適しています。

仕様書
---

| Specification |
| --- |
| HTML Standard # dom-img-sizes |

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

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

関連情報
----

* メディアクエリー
* メディアクエリーの使用
* HTML における画像
* レスポンシブ画像


HTMLImageElement: border プロパティ - Web API

HTMLImageElement: border プロパティ
==============================

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

廃止された `HTMLImageElement` の **`border`** プロパティは、 画像を囲む境界線の太さをピクセル数で指定します。既定値である 0 は、境界線を描画しないことを示します。

このプロパティは使用しないでください。代わりに、 CSS を使用して境界線をスタイル付けしてください。 `border` プロパティまたはその個別指定プロパティを使用すると、境界線の太さを設定するだけでなく、他の様々なスタイリングオプションを適用できる可能性があります。

具体的には、書字方向を意識した `border-block-start-width`, `border-block-end-width`, `border-inline-start-width`, `border-inline-end-width` 属性を用いて制御されます。

互換性（あるいはその他の理由）のために、代わりに（あるいは追加で）古いプロパティを使用することができます。 `border-top-width`, `border-right-width`, `border-bottom-width`, `border-left-width` です。

値
-

画像を囲む境界線の太さを CSS ピクセル単位で指定した整数値が入った文字列です。`0` または空文字列は、境界線を描画しないことを意味します。`border` の既定の値は `0` です。

使用上の注意
------

`border` は使わないでください。これは時代遅れです。代わりに、CSS の `border` プロパティとその個別指定プロパティを使用して、画像の周りに境界線をを設定してください。

例えば、以下のような HTML があった場合です。

```html
<img src="image.png" border="2" />
```

以下は、この廃止されたプロパティの代わりに、CSS を使用して同じ外観を提供するものです。

```html
<img src="image.png" style="border: 2px;" />
```

さらに追加情報を入力することで、境界線の色などを変更することができます。

```html
<img src="image.png" style="border: dashed 2px #333388;" />
```

仕様書
---

| Specification |
| --- |
| HTML Standard # dom-img-border |

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

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


HTMLImageElement: name プロパティ - Web API

HTMLImageElement: name プロパティ
============================

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

`HTMLImageElement` インターフェイスの **`name`** プロパティは非推奨で、要素の名前を指定します。これは、全ての要素で利用可能な `id` プロパティに置き換えられました。

値
-

画像を参照するための名前を指定する文字列。

**警告:** このプロパティは非推奨であり、後方互換性のために仕様に残っているだけです。このプロパティは `id` と同じように機能するため、代わりにこれを使用することができますし、また使用すべきです。

仕様書
---

| Specification |
| --- |
| HTML Standard # attr-img-name |

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

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


HTMLImageElement: currentSrc プロパティ - Web API

HTMLImageElement: currentSrc プロパティ
==================================

`HTMLImageElement` の **`currentSrc`** プロパティは読み取り専用で、表す `<img>` 要素で現在表示されている画像の URL を表します。

値
-

`HTMLImageElement` で表される `<img>` 要素の中で、現在表示されている画像の完全な URL を示す文字列です。これは、`sizes` や `HTMLImageElement.srcset` 属性を用いて複数の画像オプションを提供する場合に有用です。`currentSrc` を使用すると、提供された画像セットの中からブラウザーがどの画像を選択したかを判断することができます。

例
-

この例では、時計の画像に 2 種類のサイズを用意しています。一つは幅 200px で、もう一つは幅 400px です。 `sizes` 属性は、ビューポートが幅 400px 未満の場合は画像を文書幅の 50% で、それ以外の場合は画像を文書幅の 90% で描画することを指定しています。

### HTML

```html
<img
 src="/files/16797/clock-demo-400px.png"
 alt="Clock"
 srcset="
 /en-US/docs/Web/HTML/Element/img/clock-demo-200px.png 200w,
 /en-US/docs/Web/HTML/Element/img/clock-demo-400px.png 400w
 "
 sizes="(max-width: 400px) 50%, 90%" />
```

### JavaScript

```js
const clockImage = document.querySelector("img");
const p = document.createElement("p");

p.textContent = clockImage.currentSrc.endsWith("200px.png")
  ? "Using the 400px image!"
  : "Using the 200px image.";
document.body.appendChild(p);
```

### 結果

仕様書
---

| Specification |
| --- |
| HTML Standard # dom-img-currentsrc-dev |

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

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


HTMLImageElement: naturalWidth プロパティ - Web API

HTMLImageElement: naturalWidth プロパティ
====================================

`HTMLImageElement` インターフェイスの
 **`naturalWidth`** プロパティは読み取り専用で、画像の本来の（自然な）密度補正された幅をCSS ピクセル数で返します。

これは，何も制約を受けずに描画した場合の画像の幅です。画像の幅を指定しなかった場合、または画像の幅を制限するか明示するコンテナー内に画像を配置する場合、この値は画像の幅を CSS で指定されたピクセル数で表します。

対応する `naturalHeight` メソッドは、画像の自然な高さを返します。

**メモ:** ほとんどの場合、自然な幅とは、サーバーから送信された画像の実際の幅です。とはいえ、ブラウザーは画像をレンダラーに送る前に画像を修正することがあります。たとえば、Chrome はローエンド端末で画像の解像度を低下させます。このような場合、`naturalWidth` はそのようなブラウザーの介入によって修正された画像の幅を自然な幅とみなして、この値を返します。

値
-

画像の幅を CSS ピクセル単位で表した整数値。これは、画像に制約や特定の値が設定されていない場合に、画像が自然に描画される幅です。この自然な幅は、 `width` とは異なり、表示されている端末のピクセル密度に合わせて補正されます。

画像に含まれる幅が指定されていない場合や、この情報を取得するための画像データが存在しない場合など、幅が利用できない場合は、 `naturalWidth` は 0 を返します。

例
-

画像を「密度調整された」自然のサイズと、ページの CSS やその他の要素によって変化した表示サイズの両方で表示するコードの例としては、`HTMLImageElement.naturalHeight` を参照してください。

仕様書
---

| Specification |
| --- |
| HTML Standard # dom-img-naturalwidth-dev |

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

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