移譲可能オブジェクト - Web API

移譲可能オブジェクト
==========

**移譲可能オブジェクト** (Transferable objects) は、あるコンテキストから別のコンテキストへ *移譲* することができるリソースを自分自身で所有するオブジェクトで、そのリソースが一度に 1 つのコンテキストでのみ利用できることを保証するものです。
 移譲が終わると、元のオブジェクトは使えなくなります。移譲されたリソースをもう指しておらず、オブジェクトの読み書きをしようとすると例外が発生します。

 移譲可能なオブジェクトは一般的に、一度に単一のJavaScriptスレッドにしか安全に公開されないリソースを共有するために使用されます。
 例えば、`ArrayBuffer` はメモリーブロックを自分自身で所有する移譲可能なオブジェクトです。
 このようなバッファーがスレッド間で移譲されるとき、関連するメモリーリソースは元のバッファーから切り離され、新しいスレッドで作成されたバッファーオブジェクトに装着されます。
 元のスレッドのバッファーオブジェクトは、もはやメモリリソースを所有していないため、使用できなくなります。

 移譲は `structuredClone()` でオブジェクトのディープコピーを作成するときにも使用されるかもしれません。
 複製操作の後に、移譲されたリソースは、コピーされたオブジェクトにコピーされるのではなく、移動されます。

 オブジェクトのリソースを移譲するために使用されるメカニズムは、オブジェクトに依存します。
 例えば、 `ArrayBuffer` がスレッド間で移譲されるとき、それが指すメモリーリソースは高速で効率の良いゼロコピー操作により、文字通りコンテキスト間で移動されます。
 他にも、関連するリソースをコピーして、古いコンテキストから削除することで、オブジェクトを移譲することができる場合もあります。

 すべてのオブジェクトが移譲可能なわけではありません。
 移譲可能なオブジェクトの一覧は下記の通りです。

オブジェクトのスレッド間の移譲
---------------

 以下のコードは、メインスレッドからウェブワーカースレッドにメッセージを送信する際に、移譲がどのように動作するのかを示しています。
 `Uint8Array` は、バッファーが移譲されている間、ワーカー内でコピーされます（複製されます）。
 移譲後、メインスレッドから `uInt8Array` を読み書きしようとするとエラーが発生しますが、`byteLength` を調べるとゼロになったことが確認できます。

```js
// 8MB の "file" を作成して中身を埋めます。 8MB = 1024 \* 1024 \* 8 B
const uInt8Array = new Uint8Array(1024 \* 1024 \* 8).map((v, i) => i);
console.log(uInt8Array.byteLength); // 8388608

// 下層のバッファーからワーカーに移譲する
worker.postMessage(uInt8Array, [uInt8Array.buffer]);
console.log(uInt8Array.byteLength); // 0
```

**メモ:** 型付き配列 `Int32Array` や `Uint8Array` はシリアライズ可能ですが、移譲は行えません。
 しかし、その下にあるバッファーは `ArrayBuffer` であり、これは移譲可能なオブジェクトです。
 data 引数に `uInt8Array.buffer` を設定すれば、移譲する配列に `uInt8Array` がなくても、送ることができます。

### 複製操作中の移譲について

以下のコードは、 `structuredClone()` 操作で、基礎となるバッファーが元のオブジェクトから複製にコピーされる様子を示しています。

```js
const original = new Uint8Array(1024);
const clone = structuredClone(original);
console.log(original.byteLength); // 1024
console.log(clone.byteLength); // 1024

original[0] = 1;
console.log(clone[0]); // 0

// Uint8Array を移譲すると、移譲可能なオブジェクトではないため、例外が発生します。
// const transferred = structuredClone(original, {transfer: [original]});

// Uint8Array.buffer ならば移譲できます。
const transferred = structuredClone(original, { transfer: [original.buffer] });
console.log(transferred.byteLength); // 1024
console.log(transferred[0]); // 1

// Uint8Array.buffer は移譲した後は使用することができません。
console.log(original.byteLength); // 0
```

対応しているオブジェクト
------------

各種仕様書が示す移譲可能な項目は以下の通りです。

* `ArrayBuffer`
* `MessagePort`
* `ReadableStream`
* `WritableStream`
* `TransformStream`
* `AudioData` (en-US)
* `ImageBitmap`
* `VideoFrame` (en-US)
* `OffscreenCanvas` (en-US)
* `RTCDataChannel`

 ブラウザーの対応は、それぞれのオブジェクトの互換性情報の `transferable` サブ機能で示す必要があります（例として `RTCDataChannel` を参照してください）。
 この記事を書いている時点では、すべての移譲可能なオブジェクトでこの情報が更新されているわけではありません。

**メモ:** 移譲可能なオブジェクトは Web IDL ファイル の中で `[Transferable]` という属性でマークアップされています。

関連情報
----

* Transferable Objects: Lightning Fast!
* ウェブワーカーの使用
* Transferable objects in the HTML specification
* `DedicatedWorkerGlobalScope.postMessage()`


ウェブワーカーが使用できる関数やクラス - Web API

ウェブワーカーが使用できる関数やクラス
===================

標準的な JavaScript の関数群（`String`、`Array`、`Object`、`JSON` など）に加えて、DOM からワーカーに利用できる様々な関数があります。この記事ではそれらの機能のリストを提供します。

ワーカーのコンテキストと関数
--------------

**ワーカーは、現在のウィンドウとは異なるグローバルコンテキストで実行されます。** `Window` はワーカーでは直接使用することができませんが、共通のミックスイン (`WindowOrWorkerGlobalScope`) で定義されている同じメソッドの多くが利用でき、 `WorkerGlobalScope` から派生した以下のようなコンテキストからワーカーが利用できます。

* `DedicatedWorkerGlobalScope` （専用ワーカー向け）
* `SharedWorkerGlobalScope` （共有ワーカー向け）
* `ServiceWorkerGlobalScope` （サービスワーカー向け）

すべてのワーカーとメインスレッドで共通の関数には（`WindowOrWorkerGlobalScope` にあるもの）には、 `atob()`, `btoa()`, `clearInterval()`, `clearTimeout()`, `dump()`
Non-standard
, `setInterval()`, `setTimeout()` などがあります。

以下の機能は、ワーカーで**のみ**使用することができます。

* `WorkerGlobalScope.importScripts()` （すべてのワーカー）
* `DedicatedWorkerGlobalScope.postMessage` （専用ワーカーのみ）
ワーカーで使用できる API
--------------

**メモ:** 掲載されている API に特定のバージョンのプラットフォームが対応している場合、一般にウェブワーカーで動作するとみなすことができます。

以下の Web API はワーカーで利用することができます。 `Broadcast Channel API`, `Cache API`, `Channel Messaging API`, `Console API`, `Crypto`, `CustomEvent`, `DOMRequest` と `DOMCursor`, `Fetch`, `FileReader`, `FileReaderSync` (only works in workers!), `FormData`, `ImageData`, `IndexedDB`, ネットワーク情報 API, 通知, `Performance`, `PerformanceEntry`, `PerformanceMeasure`, `PerformanceMark`, `PerformanceObserver`, `PerformanceResourceTiming`, `Promise`, サーバー送信イベント, `ServiceWorkerRegistration`, `TextEncoder` と `TextDecoder`, `URL`, WebGL と `OffscreenCanvas` (en-US), `WebSocket`, `XMLHttpRequest` （ただし `responseXML` および `channel` 属性は常に null）。

ワーカーは他のワーカーを起動することもできるため、 `Worker`, `WorkerGlobalScope`, `WorkerLocation`, `WorkerNavigator` の各 API も利用することができます。

関連情報
----

* ウェブワーカーの使用
* `Worker`


構造化複製アルゴリズム - Web API

構造化複製アルゴリズム
===========

**構造化複製アルゴリズム** は複雑な JavaScript オブジェクトをコピーするためのアルゴリズムです。これは `postMessage()` を介してワーカーと送受信するとき、 IndexedDB にオブジェクトを格納するとき、他の API のためにオブジェクトをコピーするときなど、データ転送時に内部で用いられています。

無限ループを避けるため、以前にアクセスした参照のマップを保持しながら、入力オブジェクトを再帰処理することで複製していきます。

構造化複製で動作しないもの
-------------

* `Function` オブジェクトは構造化複製アルゴリズムでは複製されません。複製しようとすると `DataCloneError` 例外が発生します。
* DOM ノードを複製するときも同様に `DataCloneError` 例外発生します。
* 一部のオブジェクトのプロパティは保持されません。
    + `RegExp` オブジェクトの `lastIndex` フィールドは保持されません。
    + プロパティ記述子、セッター、ゲッター（もしくは同様のメタデータ系機能）は複製されません。
     たとえば、あるオブジェクトがプロパティ記述子によって読み取り専用になっている場合でも、複製したものでは既定の条件である読み取り/書き込みに変わります。
    + プロトタイプチェーンは探索、複製されません。
対応済みの型
------

| オブジェクト型 | 備考 |
| --- | --- |
| すべてのプリミティブ型 | ただし、シンボルを除く |
| `Boolean` オブジェクト |  |
| `String` オブジェクト |  |
| `Date` |  |
| `RegExp` | `lastIndex` は保持されません。 |
| `Blob` |  |
| `File` |  |
| `FileList` |  |
| `ArrayBuffer` |  |
| `TypedArray` |  |
| `DataView` |  |
| `ImageBitmap` |  |
| `ImageData` |  |
| `Array` |  |
| `Object` | プレーンなオブジェクト（オブジェクトリテラルなど）**のみ**です。 |
| `Map` |  |
| `Set` |  |
| `DOMException` |
 ブラウザーは、プロパティ `name` と `message` をシリアライズしなければなりません。
 他の属性もシリアライズ/複製することができます。
  |
| ネイティブの `Error` 型 | エラー名は、 `Error`, `EvalError`, `RangeError`, `ReferenceError`, `SyntaxError`, `TypeError`, `URIError` （または "Error" に設定）の何れかでなければなりません。
ブラウザーは `name` および `message` プロパティをシリアライズしなければならず、 `stack`, `cause` などのエラーの他の「興味深い」プロパティをシリアライズすることが期待されています。
`AggregateError` の対応が whatwg/html#5749 で仕様書に追加される予定です（そして、既に一部のブラウザーが対応しています）。 |

関連情報
----

* HTML Specification: Safe passing of structured data
* Transferable objects
* `structuredClone()`
* `window.history`
* `window.postMessage()`
* ウェブワーカー
* IndexedDB


ウェブワーカーの使用 - Web API

ウェブワーカーの使用
==========

ウェブワーカーは、ウェブコンテンツがスクリプトをバックグラウンドのスレッドで実行するためのシンプルな手段です。ワーカースレッドは、ユーザーインターフェイスを妨げることなくタスクを実行できます。加えて、 `XMLHttpRequest` （`responseXML` 属性や `channel` 属性は常に null ですが）または `fetch` （そのような制約なし）を使用して入出力を行うこともできます。ワーカーが生成されると、それを作成した JavaScript コードが指定するイベントハンドラーにメッセージを投稿することで、そのコードにメッセージを送ることができます（逆も同様）。

この記事では、ウェブワーカーを使用するための詳しい紹介をしています。

ウェブワーカー API
-----------

ワーカーはコンストラクター（`Worker()` など）を使用して生成されるオブジェクトであり、名前付きの JavaScript ファイル（このファイルはワーカースレッドで実行するコードを持ちます）を実行します。またワーカーは、現在の `window` とは異なるグローバルコンテキストで実行されます。従って、 `window` を（`self` の代わりに）使用して現在のグローバルスコープを取得しようとすると、 `Worker` の中ではエラーが返されます。

ワーカーのコンテキストは、専用ワーカー（単一のスクリプトで利用される標準的なワーカー）の場合は `DedicatedWorkerGlobalScope` オブジェクトで表されます（共有ワーカーの場合は `SharedWorkerGlobalScope` です）。専用ワーカーは、最初にワーカーを起動したスクリプトだけがアクセスできます。一方、共有ワーカーは複数のスクリプトからアクセスできます。

**メモ:** ワーカーのリファレンスドキュメントや追加のガイドについては、ウェブワーカー API のトップページをご覧ください。

ワーカースレッドでは、どのようなコードでも実行できますが、いくつかの制限があります。例えば、ワーカー内から直接 DOM を操作することはできません。また `window` オブジェクトの既定のメソッドやプロパティで、使用できないものがあります。それでも、`window` 配下にある多数の項目、たとえば WebSocket や、 IndexedDB のようなデータストレージ機構などを使用できます。詳しくはワーカーで使用できる関数やクラスをご覧ください。

ワーカーとメインスレッドの間でデータをやり取りするには、メッセージの仕組みが使用されます。どちらも `postMessage()` メソッドを使用してメッセージを送信し、`onmessage` イベントハンドラーによってメッセージに応答します（メッセージは `message` イベントの data 属性に収められます）。データは共有されず、複製されます。

ワーカーは、親ページと同じオリジン内でホスティングされている場合に限り、さらに新たなワーカーを起動することができます。また、ワーカーは `XMLHttpRequest` を使用してネットワーク I/O を行うことができますが、例外として `XMLHttpRequest` の `responseXML` および `channel` 属性は常に `null` を返します。

専用ワーカー
------

前述のとおり、専用ワーカー (dedicated worker) には呼び出し元のスクリプトだけがアクセスできます。この節では基本的な専用ワーカーのサンプルにある JavaScript を見ていきます（専用ワーカーを実行する）。これは、 2 つの数字を入力して掛け合わせることができるものです。数字は専用のワーカーに送られて掛け合わされ、その結果がページに戻されて表示されます。

これはあまり面白みのないサンプルですが、基本的なワーカーの概念を紹介する間はシンプルに保とうと考えています。より高度な詳細情報は、この記事の後半で扱います。

### ワーカー機能の検出

エラー制御と後方互換性を向上させるため、ワーカーにアクセスするコードは以下のコードの中に入れるといいでしょう (main.js)。

```js
if (window.Worker) {
  // …
}
```

### 専用ワーカーの起動

新しいワーカーは簡単に生成できます。必要なことは、ワーカースレッドで実行するスクリプトの URI を指定した `Worker()` コンストラクターを呼び出すことだけです (main.js)。

```js
const myWorker = new Worker("worker.js");
```

### 専用ワーカーとのメッセージのやりとり

ワーカーのマジックは、`postMessage()` メソッドと `onmessage` イベントハンドラーによって実現します。ワーカーにメッセージを送りたいときは、以下のようにしてメッセージを送信します (main.js)。

```js
first.onchange = () => {
  myWorker.postMessage([first.value, second.value]);
  console.log("Message posted to worker");
};

second.onchange = () => {
  myWorker.postMessage([first.value, second.value]);
  console.log("Message posted to worker");
};
```

2 つの `<input>` 要素があり、それぞれ変数 `first` と `second` で表されています。どちらかの値が変化すると、 `myWorker.postMessage([first.value,second.value])` を使用して、双方の値を配列としてワーカーに送信します。メッセージでは、おおむねどのようなものでも送信できます。

ワーカー内では、以下のようにイベントハンドラーのブロックにコードを記述すると、メッセージを受け取ったときに応答できます (worker.js)。

```js
onmessage = (e) => {
  console.log("Message received from main script");
  const workerResult = `Result: ${e.data[0] \* e.data[1]}`;
  console.log("Posting message back to main script");
  postMessage(workerResult);
};
```

`onmessage` ハンドラーにより、メッセージを受け取ったときになんらかののコードを実行できます。メッセージ自体は、`message` イベントの `data` 属性で手に入ります。ここでは 2 つの数値で乗算を行った後、再び `postMessage()` を使用して計算結果をメインスレッドに返しています。

メインスレッドに戻ると、再び `onmessage` を使用して、ワーカーから返されたメッセージに応答します。

```js
myWorker.onmessage = (e) => {
  result.textContent = e.data;
  console.log("Message received from worker");
};
```

ここではメッセージイベントからデータを取り出して、結果の段落の `textContent` へ格納しています。よって、ユーザーは計算結果を見ることができます。

**メモ:** メインのスクリプトスレッドで `onmessage` および `postMessage()` を使用するときは `Worker` オブジェクトにぶら下げなければなりませんが、ワーカー内ではそのようにする必要はありません。これは、ワーカー内ではそれ自身が実質的にグローバルスコープであるためです。

**メモ:** メッセージをメインスレッドとワーカーの間でやりとりするとき、共有されるのではなく、複製または「転送」（移動）されます。詳しい解説は、ワーカーとのデータ転送の詳細をご覧ください。

### ワーカーの終了

メインスレッドから実行しているワーカーを直ちに終了させる必要がある場合は、ワーカーの `terminate` メソッドを呼び出してください。

```js
myWorker.terminate();
```

ワーカースレッドは直ちに終了します。

### エラー処理

ワーカー内で実行時エラーが発生すると、 `onerror` イベントハンドラーが呼び出されます。これは `error` という名前のイベントを受け取りますが、これは `ErrorEvent` インターフェイスを実装しています。

イベントはバブリングせず、またキャンセルすることができます。ワーカーはエラーイベントの `preventDefault()` メソッドを呼び出すことで、発生元の既定のアクションを抑制することができます。

エラーイベントには、以下の重要な 3 つのフィールドがあります。

`message`

人間が読み取れるエラーメッセージです。

`filename`

エラーが発生したスクリプトのファイル名です。

`lineno`

スクリプトファイル内でエラーが発生した場所の行番号です。

### サブワーカーの起動

ワーカーは、必要に応じてさらに多くのワーカーを生み出すことができます。いわゆるサブワーカーは、親ページと同じオリジン内でホストされていなければなりません。また、サブワーカーの URI は、親ページのものではなく、親ワーカーの位置を基準に解決されます。これにより、ワーカーは自分の依存関係がどこにあるかを簡単に把握することができます。

### スクリプトやライブラリーのインポート

Worker スレッドはグローバル関数や、スクリプトをインポートするための `importScripts()` にアクセスできます。これはインポートするリソースの URI を 0 個以上、引数として受け入れます。以下の例はすべて有効です。

```js
importScripts(); /\* 何もインポートしない \*/
importScripts("foo.js"); /\* "foo.js" をインポート \*/
importScripts("foo.js", "bar.js"); /\* 2 つのスクリプトをインポート \*/
importScripts(
  "//example.com/hello.js",
); /\* 他のオリジンのスクリプトをインポートすることができる \*/
```

ブラウザーはそれぞれのスクリプトを読み込み、実行します。ワーカーは各スクリプトのグローバルオブジェクトを使用できます。スクリプトを読み込むことができない場合は `NETWORK_ERROR` を発生させて、それ以降のコードを実行しません。それでも、すでに実行されたコード（`setTimeout()` で繰り延べされているコードを含みます）は動作します。`importScripts()` メソッドより**後方**にある関数の宣言は、常にコードの残りの部分より先に評価されることから、同様に保持されます。

**メモ:** スクリプトは順不同にダウンロードされることがありますが、実行は `importScripts()` に渡したファイル名の順に行います。これは同期的に行われます。すべてのスクリプトの読み込みと実行が行われるまで `importScripts()` から戻りません。

共有ワーカー
------

共有ワーカーは、オリジンが同一であれば（異なるウィンドウ、iframe、ワーカーからであっても）複数のスクリプトからアクセスできます。本章では基本的な共有ワーカーの例 の JavaScript を見ていきます (共有ワーカーを実行する)。こちらは専用ワーカーのサンプルと似ていますが、*2 つの数値で乗算を行う*スクリプトと*数値を 2 乗する*スクリプトという、別々のスクリプトファイルが扱う 2 つの関数を使用できる点が異なります。どちらのスクリプトも同じワーカーを使用して、実際に必要な計算を行います。

ここでは、 専用ワーカーと共有ワーカーの違いについて注目します。この例では 2 つの HTML ページがあり、それぞれの JavaScript は同じ単一のワーカーファイルを使用するようになっています。

**メモ:** 共有ワーカーが複数の閲覧コンテキストからアクセスできる場合、すべての閲覧コンテキストはまったく同じオリジン (プロトコル、ホスト、ポート番号が同じ) になります。

**メモ:** Firefox では、共有ワーカーはプライベートウィンドウとそれ以外に読み込まれた文書間で共有することができません (Firefox バグ 1177621)。

### 共有ワーカーの生成

新しい共有ワーカーの生成方法は 専用ワーカー の場合とほとんど同じですが、コンストラクター名が異なります（index.html および index2.html をご覧ください）。それぞれのページで、以下のようなコードを使用してワーカーを立ち上げます。

```js
const myWorker = new SharedWorker("worker.js");
```

共有ワーカーの大きな違いのひとつが、 `port` オブジェクトを通して通信しなければならないことです。スクリプトがワーカーと通信するために使用できる、明示的なポートが開きます (これは、 専用ワーカーでも暗黙的に開いています)。

ポートへの接続は、メッセージを送信する前に `onmessage` イベントハンドラーを使用して暗黙的に行うか、あるいは `start()` メソッドを使用して明示的に開始するかしなければなりません。 `start()` の呼び出しは、`addEventListener()` メソッドで `message` イベントを拾い上げる場合にのみ必要です。

**メモ:** ポート接続を開始するために `start()` メソッドを使用するとき、双方向の通信が必要である場合は親スレッドとワーカーの両方で呼び出さなければなりません。

### 共有ワーカーとのメッセージのやりとり

前述のとおりワーカーにメッセージを送信できるようになりましたが、`postMessage()` メソッドは port オブジェクトを通して呼び出さなければなりません（繰り返しますが、同様の構造が multiply.js および square.js に存在します）。

```js
squareNumber.onchange = () => {
  myWorker.port.postMessage([squareNumber.value, squareNumber.value]);
  console.log("Message posted to worker");
};
```

ワーカーに移ります。こちらは若干複雑さが増しています (worker.js):

```js
onconnect = (e) => {
  const port = e.ports[0];

  port.onmessage = (e) => {
    const workerResult = `Result: ${e.data[0] \* e.data[1]}`;
    port.postMessage(workerResult);
  };
};
```

始めに、ポートへの接続が発生したとき（すなわち、親スレッドで `onmessage` イベントをセットアップしたときや親スレッドで `start()` メソッドを明示的に呼び出したとき）にコードを実行するため `onconnect` ハンドラーを使用します。

イベントオブジェクトの `ports` 属性を使用してポートを取り出し、変数に格納します。

次に、計算を実行して結果をメインスレッドに返すため、ポートの `message` のハンドラーを使用します。ワーカースレッドで `message` のハンドラーをセットアップすると、親スレッドに戻すポート接続を暗黙的に開きます。従って、実際は前述のとおり `port.start()` を呼び出す必要はありません。

最後に、メインスレッドに戻ってメッセージを扱います（繰り返しますが、同様の構造が multiply.js および square.js) に存在します）。

```js
myWorker.port.onmessage = (e) => {
  result2.textContent = e.data;
  console.log("Message received from worker");
};
```

ポートを通してワーカーからメッセージが戻ったときは、結果のデータ型を確認してから適切な段落に計算結果を挿入します。

スレッドセーフについて
-----------

`Worker` インターフェイスでは、OS レベルの実際のスレッドが生成されるため、注意深いプログラマーは、注意しないと同時実行によってコードに「面白い」効果が生じるのではないかと懸念するかもしれません。

しかし、ウェブワーカーは他のスレッドとの通信ポイントが慎重に制御されているため、同時実行の問題を引き起こすことは実際には非常に困難です。スレッドセーフでないコンポーネントや DOM にはアクセスできません。また、シリアル化されたオブジェクトを通して特定のデータをスレッドに出し入れしなければなりません。ですから、コードで問題を起こすためには、かなり難しいのです。

コンテンツセキュリティポリシー
---------------

ワーカーは、自分を生成した文書から区別された独自の実行コンテキストを持っているとみなされます。このため、一般に、自分を生成した文書（または親ワーカー）のコンテンツセキュリティポリシーでは管理されません。そのため例えば、文書が次のヘッダー付きで読み込まれたと仮定します。

```http
Content-Security-Policy: script-src 'self'
```

特に、これは `eval()` を使用したスクリプトを防ぎます。しかし、スクリプトがワーカーを構築した場合、ワーカーのコンテキストで実行中のコードは `eval()` を使用することができます。

ワーカーのコンテンツセキュリティポリシーを指定するには、ワーカースクリプト自身が配信されたリクエストの Content-Security-Policy レスポンスヘッダーで設定してください。

ワーカースクリプトのオリジンがグローバルに一意な識別子である場合（例えば、 URL のスキームが data や blob であった場合）は例外です。この場合、ワーカーは文書の CSP またはそれを作成したワーカーを継承します。

ワーカーとのデータ転送の詳細
--------------

メインページとワーカーの間で渡されるデータは、共有ではなく**コピー**されます。オブジェクトは、ワーカーに渡されるときにシリアライズされ、その後、反対側でシリアライズが解除されます。ページとワーカーは**同じインスタンスを共有しない**ため、最終的には両側に**複製**が作成されます。ほとんどのブラウザーはこの機能を構造化複製として実装しています。

これを説明するため、教育的な用途の関数 `emulateMessage()` を作成し、 `worker` からメインページおよびその逆の移動において*共有されず複製される*値の動作をシミュレーションしてみましょう。

```js
function emulateMessage(vVal) {
  return eval(`(${JSON.stringify(vVal)})`);
}

// テスト

// テスト #1
const example1 = new Number(3);
console.log(typeof example1); // object
console.log(typeof emulateMessage(example1)); // number

// テスト #2
const example2 = true;
console.log(typeof example2); // boolean
console.log(typeof emulateMessage(example2)); // boolean

// テスト #3
const example3 = new String("Hello World");
console.log(typeof example3); // object
console.log(typeof emulateMessage(example3)); // string

// テスト #4
const example4 = {
  name: "John Smith",
  age: 43,
};
console.log(typeof example4); // object
console.log(typeof emulateMessage(example4)); // object

// テスト #5
function Animal(type, age) {
  this.type = type;
  this.age = age;
}
const example5 = new Animal("Cat", 3);
alert(example5.constructor); // Animal
alert(emulateMessage(example5).constructor); // Object
```

複製され、共有されない値を*メッセージ*と呼びます。もうお分かりだと思いますが、*メッセージ*は `postMessage()` を使ってメインスレッドとの間で送受信することができ、 `message` イベントの `data` 属性には、ワーカーから返されたデータが含まれています。

**example.html** （メインページ）

```js
const myWorker = new Worker("my\_task.js");

myWorker.onmessage = (event) => {
  console.log(`Worker said : ${event.data}`);
};

myWorker.postMessage("ali");
```

**my\_task.js** （ワーカー）

```js
postMessage("I'm working before postMessage('ali').");

onmessage = (event) => {
  postMessage(`Hi, ${event.data}`);
};
```

構造化複製アルゴリズムは JSON を受け入れることができ、循環参照など JSON ではできないものもいくつか受け入れることができます。

### データ引き渡しの例

#### 例 #1: 高度な JSON データ渡しと切り替えシステムの作成

もしいくつかの複雑なデータを渡さなければならず、メインページとワーカーの両方で多くの異なる関数を呼び出さなければならない場合、すべてをまとめてグループにするシステムを作ることができます。

はじめに、ワーカーの URL、既定のリスナー、エラーハンドラーを持つ `QueryableWorker` クラスを作ります。このクラスはリスナーのリストを記録し、ワーカーとのコミュニケーションに役立てます。

```js
function QueryableWorker(url, defaultListener, onError) {
  const instance = this;
  const worker = new Worker(url);
  const listeners = {};

  this.defaultListener = defaultListener ?? (() => {});

  if (onError) {
    worker.onerror = onError;
  }

  this.postMessage = (message) => {
    worker.postMessage(message);
  };

  this.terminate = () => {
    worker.terminate();
  };
}
```

そして、リスナーを追加/削除するメソッドを追加します。

```js
this.addListeners = (name, listener) => {
  listeners[name] = listener;
};

this.removeListeners = (name) => {
  delete listeners[name];
};
```

ここでは、説明のためにワーカーに 2 つの簡単な操作をさせてみましょう。 2 つの数値の差を取得することと、 3 秒後にアラートを出すことです。これを実現するために、まず最初に `sendQuery` メソッドを実装します。これは、ワーカーが実際に対応するメソッドを持っているかどうかを問い合わせるものです。

```js
// This functions takes at least one argument, the method name we want to query.
// Then we can pass in the arguments that the method needs.
this.sendQuery = (queryMethod, ...queryMethodArguments) => {
  if (!queryMethod) {
    throw new TypeError(
      "QueryableWorker.sendQuery takes at least one argument",
    );
  }
  worker.postMessage({
    queryMethod: arguments[0],
    queryArguments: Array.prototype.slice.call(arguments, 1),
  });
};
```

`QueryableWorker` を `onmessage` メソッドで終了させます。問い合わせたメソッドに対応するワーカーがあれば、対応するリスナーの名前と必要な引数を返してくれるはずなので、あとは `listeners` の中を探すだけです。

```js
worker.onmessage = (event) => {
  if (
    event.data instanceof Object &&
    Object.hasOwn(event.data, "queryMethodListener") &&
    Object.hasOwn(event.data, "queryMethodArguments")
  ) {
    listeners[event.data.queryMethodListener].apply(
      instance,
      event.data.queryMethodArguments,
    );
  } else {
    this.defaultListener.call(instance, event.data);
  }
};
```

次にワーカーです。まず、 2 つの簡単な操作を行うためのメソッドが必要です。

```js
const queryableFunctions = {
  getDifference(a, b) {
    reply("printStuff", a - b);
  },
  waitSomeTime() {
    setTimeout(() => {
      reply("doAlert", 3, "seconds");
    }, 3000);
  },
};

function reply(queryMethodListener, ...queryMethodArguments) {
  if (!queryMethodListener) {
    throw new TypeError("reply - takes at least one argument");
  }
  postMessage({
    queryMethodListener,
    queryMethodArguments,
  });
}

/\* This method is called when main page calls QueryWorker's postMessage method directly\*/
function defaultReply(message) {
  // do something
}
```

そして、`onmessage`メソッドは簡単になりました。

```js
onmessage = (event) => {
  if (
    event.data instanceof Object &&
    Object.hasOwn(event.data, "queryMethod") &&
    Object.hasOwn(event.data, "queryMethodArguments")
  ) {
    queryableFunctions[event.data.queryMethod].apply(
      self,
      event.data.queryMethodArguments,
    );
  } else {
    defaultReply(event.data);
  }
};
```

ここでは、完全な実装を紹介します。

**example.html** （メインページ）

```html
<!doctype html>
<html lang="en-US">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width" />
    <title>MDN Example - Queryable worker</title>
    <script type="text/javascript">
 // QueryableWorker instances methods:
 // \* sendQuery(queryable function name, argument to pass 1, argument to pass 2, etc. etc.): calls a Worker's queryable function
 // \* postMessage(string or JSON Data): see Worker.prototype.postMessage()
 // \* terminate(): terminates the Worker
 // \* addListener(name, function): adds a listener
 // \* removeListener(name): removes a listener
 // QueryableWorker instances properties:
 // \* defaultListener: the default listener executed only when the Worker calls the postMessage() function directly
 function QueryableWorker(url, defaultListener, onError) {
 const instance = this;
 const worker = new Worker(url);
 const listeners = {};

 this.defaultListener = defaultListener ?? (() => {});

 if (onError) {
 worker.onerror = onError;
 }

 this.postMessage = (message) => {
 worker.postMessage(message);
 };

 this.terminate = () => {
 worker.terminate();
 };

 this.addListener = (name, listener) => {
 listeners[name] = listener;
 };

 this.removeListener = (name) => {
 delete listeners[name];
 };

 // This functions takes at least one argument, the method name we want to query.
 // Then we can pass in the arguments that the method needs.
 this.sendQuery = (queryMethod, ...queryMethodArguments) => {
 if (!queryMethod) {
 throw new TypeError(
 "QueryableWorker.sendQuery takes at least one argument",
 );
 }
 worker.postMessage({
 queryMethod,
 queryMethodArguments,
 });
 };

 worker.onmessage = (event) => {
 if (
 event.data instanceof Object &&
 Object.hasOwn(event.data, "queryMethodListener") &&
 Object.hasOwn(event.data, "queryMethodArguments")
 ) {
 listeners[event.data.queryMethodListener].apply(
 instance,
 event.data.queryMethodArguments,
 );
 } else {
 this.defaultListener.call(instance, event.data);
 }
 };
 }

 // 独自の「照会可能な」 worker
 const myTask = new QueryableWorker("my\_task.js");

 // 独自の「リスナー」
 myTask.addListener("printStuff", (result) => {
 document
 .getElementById("firstLink")
 .parentNode.appendChild(
 document.createTextNode(`The difference is ${result}!`),
 );
 });

 myTask.addListener("doAlert", (time, unit) => {
 alert(`Worker waited for ${time} ${unit} :-)`);
 });
 </script>
  </head>
  <body>
    <ul>
      <li>
        <a
 id="firstLink"
 href="javascript:myTask.sendQuery('getDifference', 5, 3);"
 >What is the difference between 5 and 3?</a
 >
      </li>
      <li>
        <a href="javascript:myTask.sendQuery('waitSomeTime');"
 >Wait 3 seconds</a
 >
      </li>
      <li>
        <a href="javascript:myTask.terminate();">terminate() the Worker</a>
      </li>
    </ul>
  </body>
</html>
```

**my\_task.js** （ワーカー）

```js
const queryableFunctions = {
  // 例 #1: 2 つの値の差を得る
  getDifference(minuend, subtrahend) {
    reply("printStuff", minuend - subtrahend);
  },

  // 例 #2: 3 秒待つ
  waitSomeTime() {
    setTimeout(() => {
      reply("doAlert", 3, "seconds");
    }, 3000);
  },
};

// システム関数

function defaultReply(message) {
  // メインページが queryableWorker.postMessage() メソッドを直接呼び出したときに限り実行される、デフォルトの PUBLIC 関数
  // 何らかの処理
}

function reply(queryMethodListener, ...queryMethodArguments) {
  if (!queryMethodListener) {
    throw new TypeError("reply - not enough arguments");
  }
  postMessage({
    queryMethodListener,
    queryMethodArguments,
  });
}

onmessage = (event) => {
  if (
    event.data instanceof Object &&
    Object.hasOwn(event.data, "queryMethod") &&
    Object.hasOwn(event.data, "queryMethodArguments")
  ) {
    queryableFunctions[event.data.queryMethod].apply(
      self,
      event.data.queryMethodArguments,
    );
  } else {
    defaultReply(event.data);
  }
};
```

各メインページ → ワーカー、ワーカー → メインページとメッセージの内容を切り替えることができます。そして、 "queryMethod", "queryMethodListeners", "queryMethodArguments" の各プロパティ名は、 `QueryableWorker` とワーカーで一致していれば何でも構いません。

### 所有権の移譲によるデータの引き渡し（移譲可能オブジェクト）

現代のブラウザーには、ある種のオブジェクトをワーカーに、またはワーカーから高いパフォーマンスで渡すための別の方法があります。移譲可能オブジェクトは、あるコンテキストから別のコンテキストへゼロコピー演算を運営して転送されるので、大きなデータセットを送信するときにパフォーマンスが大幅に改善されます。

例えば、メインアプリからワーカースクリプトに `ArrayBuffer` を移譲する場合、元の `ArrayBuffer` はクリアされてもう使えなくなります。その内容は、（文字どおり）ワーカーのコンテキストに移譲されます。

```js
// 32MB の「ファイル」を作成し、 0 から 255 までの連続した値で埋めます。 – 32MB = 1024 \* 1024 \* 32
const uInt8Array = new Uint8Array(1024 \* 1024 \* 32).map((v, i) => i);
worker.postMessage(uInt8Array.buffer, [uInt8Array.buffer]);
```

埋め込みワーカー
--------

ワーカーのコードをウェブページに埋め込むための、通常のスクリプトを `<script>` 要素で埋め込むような「公式な」方法はありません。しかし、 `<script>` 要素が `src` 属性を持たず、また `type` 属性が実行可能な MIME タイプを示していない場合は、 JavaScript が使用できるデータブロック要素であると判断されます。「データブロック」はほとんどのテキストデータを持つことができる、 HTML の一般的な機能です。よって、以下の方法でワーカーを埋め込むことができます。

```html
<!doctype html>
<html lang="en-US">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width" />
    <title>MDN Example - Embedded worker</title>
    <script type="text/js-worker">
 // MIME タイプが text/js-worker であるため、このスクリプトは JS エンジンに解釈されません。
 const myVar = 'Hello World!';
 // ワーカーの残りのコードをここに置きます。
 </script>
    <script>
 // MIME タイプが text/javascript であるため、このスクリプトは JS エンジンに解釈されます。
 function pageLog(sMsg) {
 // フラグメントを使用します。ブラウザーのレンダリングや再フローを 1 回だけにします。
 const frag = document.createDocumentFragment();
 frag.appendChild(document.createTextNode(sMsg));
 frag.appendChild(document.createElement("br"));
 document.querySelector("#logDisplay").appendChild(frag);
 }
 </script>
    <script type="text/js-worker">
 // MIME タイプが text/js-worker であるため、このスクリプトは JS エンジンに解釈されません。
 onmessage = (event) => {
 postMessage(myVar);
 };
 // ワーカーの残りのコードをここに置きます。
 </script>
    <script>
 // MIME タイプが text/javascript であるため、このスクリプトは JS エンジンに解釈されます。

 // 以前は blob を構築していましたが、現在は Blob を使用します。
 const blob = new Blob(Array.prototype.map.call(
 document.querySelectorAll("script[type='text\/js-worker']"),
 (script) => script.textContent,
 { type: 'text/javascript' }
 );

 // すべての "text/js-worker" スクリプトを含む、新たな document.worker プロパティを生成します。
 document.worker = new Worker(window.URL.createObjectURL(blob));

 document.worker.onmessage = (event) => {
 pageLog(`Received: ${event.data}`);
 };

 // ワーカーを起動します。
 window.onload = () => { document.worker.postMessage(''); };
 </script>
  </head>
  <body>
    <div id="logDisplay"></div>
  </body>
</html>
```

埋め込みワーカーは、新たな `document.worker` カスタムプロパティの中に入りました。

言うまでもなく、次の例のように、関数を Blob に変換して、その blob からオブジェクトの URL を生成することができます。

```js
function fn2workerURL(fn) {
  const blob = new Blob([`(${fn.toString()})()`], { type: "text/javascript" });
  return URL.createObjectURL(blob);
}
```

追加の例
----

ここではウェブワーカーの使用方法について、さらに例を示します。

### バックグラウンドで演算を行う

ワーカーは主に、ユーザーインターフェイスのスレッドを妨げずに CPU 負荷が大きい演算を実行するために役立ちます。このサンプルでは、ワーカーをフィボナッチ数の計算に使用します。

#### JavaScript コード

以下の JavaScript コードをファイル "fibonacci.js" に保存し、次節の HTML から参照します。

```js
self.onmessage = (e) => {
  const userNum = Number(e.data);
  fibonacci(userNum);
};

function fibonacci(num) {
  let a = 1;
  let b = 0;
  while (num >= 0) {
    [a, b] = [a + b, a];
    num--;
  }

  self.postMessage(b);
}
```

ワーカーは `onmessage` プロパティを、ワーカーのオブジェクトの `postMessage()` が呼び出されたときにメッセージを受け取る関数に設定します (これはその名前の*変数*や*関数*を定義することとは違いますので注意してください。 `var onmessage` と `function onmessage` は、これらの名前のグローバルグローバルプロパティを定義しますが、ワーカーを作成したウェブページから送信されたメッセージを受信するように関数を登録するわけではありません)。これは最適に開始して、それぞれの計算の反復処理を扱うために自分自身のコピーを起動します。

#### HTML コード

```html
<!doctype html>
<html lang="en-US">
  <head>
    <meta charset="UTF-8" />
    <title>Fibonacci number generator</title>
    <style>
 body {
 width: 500px;
 }

 div,
 p {
 margin-bottom: 20px;
 }
 </style>
  </head>
  <body>
    <form>
      <div>
        <label for="number"
 >Enter a number that is an index position in the fibonacci sequence to
          see what number is in that position (e.g. enter 5 and you'll get a
          result of 8 — fibonacci index position 5 is 8).</label
 >
        <input type="number" id="number" />
      </div>
      <div>
        <input type="submit" />
      </div>
    </form>

    <p id="result"></p>

    <script>
 const form = document.querySelector("form");
 const input = document.querySelector('input[type="number"]');
 const result = document.querySelector("p#result");
 const worker = new Worker("fibonacci.js");

 worker.onmessage = (event) => {
 result.textContent = event.data;
 console.log(`Got: ${event.data}`);
 };

 worker.onerror = (error) => {
 console.log(`Worker error: ${error.message}`);
 throw error;
 };

 form.onsubmit = (e) => {
 e.preventDefault();
 worker.postMessage(input.value);
 input.value = "";
 };
 </script>
  </body>
</html>
```

ウェブページは `result` という ID を持つ `div` 要素を作成して、結果を表示するために使用します。そして、ワーカーを起動します。ワーカーを起動した後は、`onmessage` ハンドラーを `div` 要素の内容を指定することで結果を表示するように構成し、また `onerror` ハンドラーはエラーメッセージを開発者ツールのコンソールへ記録するために設定します。

最後に、ワーカーを開始するためにメッセージを送信します。

この例のデモを試してください。

### 複数のワーカーにタスクを分割する

マルチコアのコンピューターが一般的になってきたことで複数のワーカーに複雑な計算処理を分割することが有用になり、それらのタスクを複数の CPU コアで実行することが可能になります。

その他のワーカー
--------

専用ワーカーや共有ワーカーに加えて、利用できる他の種類のワーカーがあります。

* サービスワーカー は、基本的に、ウェブアプリケーションと、ブラウザーおよびネットワーク (利用可能な場合) との間に位置するプロキシーサーバーとして機能します。これは、効果的なオフライン操作の構築ができるようにすること目的としています。ネットワークリクエストを傍受し、ネットワークが利用可能かどうかや、サーバー上の更新された資産に基づいて、適切なアクションをとります。また、プッシュ通知やバックグラウンド同期の API にもアクセスできるようになります。
* オーディオワークレット は、ワークレット（ワーカーの軽量版）のコンテキスト内でスクリプトによる音声処理を直接実行する機能を提供します。
ワーカースレッドのデバッグ
-------------

ほとんどのブラウザーは、 JavaScript デバッガーでワーカースレッドのデバッグを、メインスレッドのデバッグとまったく同じ方法で対応しています。たとえば、 Firefox と Chrome の両方で、メインスレッドとアクティブなワーカースレッドの両方の JavaScript ソースファイルを一覧表示し、これらのファイルをすべて開いてブレークポイントやログポイントを設定することができます。

ウェブワーカーをデバッグする方法については、各ブラウザーの JavaScript デバッガーのドキュメントを参照してください。

* Chrome のソースパネル
* Firefox の JavaScript デバッガー
ワーカーで使用できる関数とインターフェイス
---------------------

標準的な JavaScript 機能のほとんどがウェブワーカー内で使用できます。以下のものを含みます。

* `Navigator`
* `XMLHttpRequest`
* `Array`、`Date`、`Math`、`String`
* `setTimeout()` および `setInterval()`

ワーカーで*実行できない*ことは主に、親ページに直接影響を与えるものです。これは、 DOM の操作やページのオブジェクトを使用することを含みます。`DedicatedWorkerGlobalScope.postMessage` を使用してメインスクリプトにメッセージを戻してから変更操作を行う形で、間接的に実行しなければなりません。

**メモ:** あるメソッドがワーカーで利用できるかどうかは、サイト https://worker-playground.glitch.me/ を使ってテストできます。例えば、Firefox 84 でサイトに EventSource と入力すると、サービスワーカーではサポートされていないが、専用ワーカーや共有ワーカーではサポートされていることがわかります。

**メモ:** ワーカーで使用できる関数の完全なリストは、ワーカーで使用できる関数とインターフェイスでご覧ください。

仕様書
---

| Specification |
| --- |
| HTML Standard # workers |

関連情報
----

* `Worker` インターフェイス
* `SharedWorker` インターフェイス
* ワーカーで使用できる関数
* `OffscreenCanvas` (en-US) インターフェイス


MediaCapabilitiesInfo - Web API

MediaCapabilitiesInfo
=====================

Media Capabilities API (en-US) の **`MediaCapabilitiesInfo`** インターフェイスは、`MediaCapabilities` (en-US) インターフェイスの `MediaCapabilities.encodingInfo()` メソッドまたは `MediaCapabilities.decodingInfo()` (en-US) メソッドによって返される promise が満たされると使用可能になり、メディアタイプがサポートされているかどうかや、そのようなメディアのエンコードまたはデコードがスムーズで電力効率が良いかどうかに関する情報を提供します。

プロパティ
-----

`MediaCapabilitiesInfo` インターフェイスには、次の 3 つの Boolean 属性が含まれています。

* `supported`: `MediaConfiguration` で定義されたプロパティを指定すると、指定されたメディアコンテンツをエンコード（`MediaEncodingConfiguration` (en-US) が設定されている場合）またはデコード（`MediaDecodingConfiguration` (en-US) が設定されている場合）できますか？ はいの場合、`supported` は *true* になり、そうでない場合、*false* になります。
* `smooth`: `MediaConfiguration` で定義されたプロパティを指定すると、指定されたメディアの再生は高品質になりますか？ スムーズになりますか？ `supported` が `true` で、再生がスムーズになる場合、`smooth` は *true* になり、そうでない場合、*false* になります。
* `powerEfficient`: `MediaConfiguration` で定義されたプロパティを指定すると、指定されたメディアの再生は電力効率が良くなりますか？ `supported` が `true` で、再生の電力効率が良い場合、`powerEfficient` は *true* になり、そうでない場合、*false* になります。

ブラウザーは、このデバイスの統計情報が記録されるまで、サポートしているメディア構成を `smooth` で `powerEfficient` として報告します。 サポートしているすべての音声コーデックは、電力効率が良いと報告されます。

例
-

```js
// テストする MediaConfiguration
const mediaConfig = {
    type : 'file',
    audio : {
        contentType : "audio/ogg",
        channels : 2,
        bitrate : 132700,
        samplerate : 5200
     },
};

// サポートとパフォーマンスを確認する
navigator.mediaCapabilities.decodingInfo(mediaConfig).then(result => { // result にはメディア能力情報が含まれます
    console.log('この構成は、サポート' +
        (result.supported ? 'され' : 'されておらず') + 、スムーズ' +   // 構成されたメディアは、ユーザーエージェントによってデコードできますか
        (result.smooth ? 'であり' : 'でなく') + '、電力効率' +         // スムーズですか？
        (result.powerEfficient ? 'に優れています' : 'が良くありません') + '。') // 電力効率は良いですか？
});
```

仕様
--

| Specification |
| --- |
| Media Capabilities # ref-for-dom-mediacapabilities-encodinginfo |

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

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

関連情報
----

* `MediaConfiguration`
* `MediaCapabilities.encodingInfo()`
* `MediaCapabilities.decodingInfo()` (en-US)


CSSRule: type プロパティ - Web API

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

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

**`type`** は `CSSRule` インターフェイスの読み取り専用プロパティで、非推奨です。この `CSSRule` が表すルールの型を示す整数を返します。

様々な CSS ルールの型を見分ける必要がある場合は、 `constructor.name` を使用するのが良い代替手段です。

```js
const sheets = Array.from(document.styleSheets);
const rules = sheets.map((sheet) => Array.from(sheet.cssRules)).flat();

for (const rule of rules) {
  console.log(rule.constructor.name);
}
```

値
-

`CSSRule.STYLE_RULE` (`1`)

このルールは `CSSStyleRule` で、 `selector { prop1: val1; prop2: val2; }` のような最も一般的な種類のルールです。

`CSSRule.IMPORT_RULE` (`3`)

このルールは `CSSImportRule` で、 `@import` ルールを表します。

`CSSRule.MEDIA_RULE` (`4`)

このルールは `CSSMediaRule` です。

`CSSRule.FONT_FACE_RULE` (`5`)

このルールは `CSSFontFaceRule` です。

`CSSRule.PAGE_RULE` (`6`)

このルールは `CSSPageRule` です。

`CSSRule.KEYFRAMES_RULE` (`7`)

このルールは `CSSKeyframesRule` です。

`CSSRule.KEYFRAME_RULE` (`8`)

このルールは `CSSKeyframeRule` です。

`CSSRule.NAMESPACE_RULE` (`10`)

このルールは `CSSNamespaceRule` です。

`CSSRule.COUNTER_STYLE_RULE` (`11`)

このルールは `CSSCounterStyleRule` (en-US) です。

`CSSRule.SUPPORTS_RULE` (`12`)

このルールは `CSSSupportsRule` です。

`CSSRule.DOCUMENT_RULE` (`13`)

このルールは `CSSDocumentRule` です。

`CSSRule.FONT_FEATURE_VALUES_RULE` (`14`)

このルールは `CSSFontFeatureValuesRule` (en-US) です。

`CSSRule.VIEWPORT_RULE` (`15`)

このルールは `CSSViewportRule` です。

`CSSRule.REGION_STYLE_RULE` (`16`)

このルールは `CSSRegionStyleRule` です。

`CSSRule.UNKNOWN_RULE` (`0`) と `CSSRule.CHARSET_RULE` (`2`) は非推奨であり、受け取ることはできません。

例
-

```js
let myRules = document.styleSheets[0].cssRules;
console.log(myRules[0].type);
```

仕様書
---

| Specification |
| --- |
| CSS Object Model (CSSOM) # concept-css-rule-type |

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

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


CSSRule: parentStyleSheet プロパティ - Web API

CSSRule: parentStyleSheet プロパティ
===============================

**`parentStyleSheet`** は `CSSRule` インターフェイスのプロパティで、現在のルールを定義している `StyleSheet` オブジェクトを返します。

値
-

`StyleSheet` オブジェクトです。

例
-

```js
const docRules = document.styleSheets[0].cssRules;
console.log(docRules[0].parentStyleSheet == document.styleSheets[0]); // returns true
```

仕様書
---

| Specification |
| --- |
| CSS Object Model (CSSOM) # dom-cssrule-parentstylesheet |

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

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


CSSRule: cssText プロパティ - Web API

CSSRule: cssText プロパティ
======================

**`cssText`** は `CSSRule` インターフェイスのプロパティで、 `CSSStyleSheet` スタイルルールの実際のテキストを返します。

**メモ:** このプロパティを要素のスタイルの `CSSStyleDeclaration.cssText` と混同しないでください。

このプロパティは、仕様化されたとおり、*機能的に*変更のみで、かつ、暗黙的であることが指定されているため、直接設定することができなくなったことに注意してください。言い換えると、設定しようとしても警告もエラーもなく、*絶対に何も起こりません*。さらに、設定可能なサブプロパティもありません。従って、これを変更するには、スタイルシートの `cssRules``[index]` プロパティおよび `.selectorText`、`.style` （または、そのサブプロパティ）を使用してください。詳細は、動的なスタイル情報の使用を参照してください。

値
-

この `CSSStyleSheet` ルールの実際のテキストを含む文字列です。

例
-

```css
body {
  background-color: darkblue;
}
```

```js
let stylesheet = document.styleSheets[0];
console.log(stylesheet.cssRules[0].cssText); // body { background-color: darkblue; }
```

仕様書
---

| Specification |
| --- |
| CSS Object Model (CSSOM) # dom-cssrule-csstext |

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

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


CSSRule: parentRule プロパティ - Web API

CSSRule: parentRule プロパティ
=========================

**`parentRule`** は `CSSRule` インターフェイスのプロパティで、現在のルールを内包するルールがあれば、それを返します。なければ null を返します。

値
-

包含するルールの型の `CSSRule` を返します。現在のルールがメディアクエリーの中にある場合は、 `CSSMediaRule` になります。包含するルールがない場合は null を返します。

例
-

```css
@media (min-width: 500px) {
  .box {
    width: 100px;
    height: 200px;
    background-color: red;
  }

  body {
    color: blue;
  }
}
```

```js
let myRules = document.styleSheets[0].cssRules;
let childRules = myRules[0].cssRules;
console.log(childRules[0].parentRule); // a CSSMediaRule
```

仕様書
---

| Specification |
| --- |
| CSS Object Model (CSSOM) # dom-cssrule-parentrule |

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

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


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

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

ウェブオーディオ API の **`ChannelSplitterNode()`** コンストラクターは、新しい `ChannelSplitterNode` オブジェクトのインスタンスを作成します。これは、入力の音声チャンネルそれぞれを別々の出力に分離するノードを表します。

構文
--

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

### 引数

`context`

このノードを関連付ける音声コンテキストを表す `BaseAudioContext` です。

`options` 省略可

`ChannelSplitterNode` に持たせるプロパティを定義するオブジェクトです。

`numberOfOutputs` 省略可

`ChannelSplitterNode` の出力の数を決める数値です。指定しない場合の既定の値は 6 です。

`channelCount` 省略可

 このノードの入力についてアップミキシングとダウンミキシングを行う際に用いるチャンネル数を決める整数です。
 (詳しくは `AudioNode.channelCount` を参照してください)
 使用法と正確な定義は `channelCountMode` の値によります。

`channelCountMode` 省略可

 ノードの入力と出力でチャンネルを対応付ける方法を表す文字列です。
 (デフォルト値など詳しくは `AudioNode.channelCountMode` を参照してください)

`channelInterpretation` 省略可

 チャンネルの意味を表す文字列です。
 この意味により、音声のアップミキシングとダウンミキシングを行う方法が決まります。
 取りうる値は `"speakers"` と `"discrete"` です。
 (デフォルト値など詳しくは `AudioNode.channelCountMode` を参照してください)

### 返値

新しい `ChannelSplitterNode` オブジェクトのインスタンスを返します。

例
-

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

const options = {
  numberOfOutputs: 2,
};

const mySplitter = new ChannelSplitterNode(ac, options);
```

仕様書
---

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

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

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


InstallEvent() - Web API

InstallEvent()
==============

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

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

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

構文
--

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

### 引数

`type`

 文字列で、イベントの名前です。
 大文字小文字の区別があり、ブラウザーは常に `install` に設定します。

`options`

オブジェクトで、*`Event()` で定義されているプロパティに加え*、以下のプロパティを持つことができます。

`activeWorker`

現在ページをアクティブに制御している `ServiceWorker` です。

返値
--

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

仕様書
---

*この機能は標準化路線にはありません。*

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

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

関連情報
----

* `Promise`
* フェッチ API


USB.getDevices() - Web API

USB.getDevices()
================

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

**安全なコンテキスト用:** この機能は一部またはすべての対応しているブラウザーにおいて、安全なコンテキスト (HTTPS) でのみ利用できます。

`USB` インターフェイスの **`getDevices`** メソッドは、接続されたペア設定済みのデバイスを表す `USBDevice` の配列で解決する `Promise` を返します｡デバイスのペア設定については、`USB.requestDevice()` を参照してください。

構文
--

```js
getDevices()
```

### 引数

なし

### 返値

`USBDevice` オブジェクトの配列で解決する `Promise` です。

例
-

以下の例では、ペア設定済みのデバイスの製品名とシリアル番号をコンソールに出力します。デバイスのペア設定については、`USB.requestDevice()` を参照してください。

```js
navigator.usb.getDevices().then((devices) => {
  console.log(`デバイス数: ${devices.length}`);
  devices.forEach((device) => {
    console.log(
      `製品名: ${device.productName} シリアル番号 ${device.serialNumber}`,
    );
  });
});
```

仕様書
---

| Specification |
| --- |
| WebUSB API # ref-for-dom-usb-getdevices② |

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

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


USB: disconnect イベント - Web API

USB: disconnect イベント
====================

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

`USB` インターフェイスの **`disconnect`** イベントは、ペア設定済みのデバイスが切断された時発火します。

構文
--

`addEventListener()` のようなメソッドでイベント名を使うか､イベントハンドラープロパティを設定します｡

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

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

イベント型
-----

`USBConnectionEvent` です｡`Event` を継承します｡

Event

USBConnectionEventイベントプロパティ
---------

*以下に挙げるプロパティに加え､親インターフェイス `Event` のプロパティも利用できます。*

`device` 読取専用

イベントが発火した対象の `USBDevice` です｡

例
-

USB デバイスが切断された時､UI を更新したいかもしれません｡

```js
navigator.usb.addEventListener("disconnect", (event) => {
  // UI から event.device を取り除く
});
```

別の方法として､`USB.ondiscconnect` イベントハンドラープロパティを使用して `disconnect` イベント用のハンドラーを設定できます｡

```js
navigator.usb.ondisconnect = (event) => {
  // UI から event.device を取り除く
};
```

仕様書
---

| Specification |
| --- |
| WebUSB API # disconnect |
| WebUSB API # ref-for-dom-usb-ondisconnect |

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

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


USB: connect イベント - Web API

USB: connect イベント
=================

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

`USB` インターフェイスの **`connect`** イベントは、ペア設定済みのデバイスが接続された時発火します。

構文
--

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

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

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

イベント型
-----

`USBConnectionEvent` です。`Event` を継承します。

Event

USBConnectionEventイベントプロパティ
---------

*以下に挙げるプロパティに加え、親インターフェイス `Event` のプロパティも利用できます。*

`device` 読取専用

イベントが発火した対象の `USBDevice` です。

例
-

USB デバイスが接続された時、UI を更新したいかもしれません。

```js
navigator.usb.addEventListener("connect", (event) => {
  // event.device を UI に追加する
});
```

別の方法として、`USB.onconnect` イベントハンドラープロパティを使用して `connect` イベント用のハンドラーを設定できます。

```js
navigator.usb.onconnect = (event) => {
  // event.device を UI に追加する
};
```

仕様書
---

| Specification |
| --- |
| WebUSB API # connect |
| WebUSB API # ref-for-dom-usb-onconnect |

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

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


USB.requestDevice() - Web API

USB.requestDevice()
===================

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

**安全なコンテキスト用:** この機能は一部またはすべての対応しているブラウザーにおいて、安全なコンテキスト (HTTPS) でのみ利用できます。

`USB` インターフェイスの **`requestDevice()`** メソッドは、指定のデバイスが見つかった場合は `USBDevice` のインスタンスで解決する `Promise` を返します｡このメソッドを呼ぶと､ユーザーエージェントのペア設定手続きを開始します｡

構文
--

```js
requestDevice(filters)
```

### 引数

`filters`

ペア設定をしたいデバイスの候補を決めるフィルターオブジェクトの配列です。それぞれのフィルターオブジェクトは、以下のプロパティーを持つことができます。

* `vendorId`
* `productId`
* `classCode`
* `subclassCode`
* `protocolCode`
* `serialNumber`

### 返値

`USBDevice` のインスタンスで解決する `Promise` です。

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

ユーザーによる一時的な有効化が必要です。この機能が動作するためには、ユーザーがページまたは UI 要素を操作する必要があります。

例
-

以下の例では、2 個の USB デバイスのうちの一つを検索します。2 個のプロダクト ID が指定されていることに注目してください。両方が `requestDevice()` に渡されています。これにより、ユーザーにペア設定するデバイスを選択してもらうユーザーエージェントの手続きを開始します。選択されたデバイスのみが `then()` に渡されます。

フィルターの数は、ユーザーエージェントが提示するデバイスの数を指定するわけではありません。例えば、プロダクト ID `0xa800` を持つ USB デバイス 1 個だけが検出された場合は、ユーザーエージェントはデバイスを 1 個だけ挙げるでしょう。一方、ユーザーエージェントがリストにあるデバイスのうち最初のものを 2 個、2 番目のものを 1 個検出した場合は、3 個全てのデバイスが挙げられるでしょう。

```js
const filters = [
  { vendorId: 0x1209, productId: 0xa800 },
  { vendorId: 0x1209, productId: 0xa850 },
];
navigator.usb
  .requestDevice({ filters })
  .then((usbDevice) => {
    console.log(`製品名: ${usbDevice.productName}`);
  })
  .catch((e) => {
    console.error(`デバイスがありません。${e}`);
  });
```

仕様書
---

| Specification |
| --- |
| WebUSB API # ref-for-dom-usb-requestdevice④ |

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

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


WebSocket: binaryType プロパティ - Web API

WebSocket: binaryType プロパティ
===========================

**`WebSocket.binaryType`** プロパティは、この WebSocke 接続によって受信されているバイナリーデータの型を制御します。

値
-

文字列です。

`"blob"`

バイナリーデータに `Blob` オブジェクトを使用します。これが既定値です。

`"arraybuffer"`

バイナリーデータに `ArrayBuffer` オブジェクトを使用します。

例
-

```js
// WebSocket 接続を作成
const socket = new WebSocket("ws://localhost:8080");

// バイナリーの型を "blob" から "arraybuffer" に変更
socket.binaryType = "arraybuffer";

// メッセージを待ち受け
socket.addEventListener("message", (event) => {
  if (event.data instanceof ArrayBuffer) {
    // バイナリーフレーム
    const view = new DataView(event.data);
    console.log(view.getInt32(0));
  } else {
    // テキストフレーム
    console.log(event.data);
  }
});
```

仕様書
---

| Specification |
| --- |
| WebSockets Standard # ref-for-dom-websocket-binarytype① |

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

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


WebSocket: open イベント - Web API

WebSocket: open イベント
====================

`open` イベントは、 `WebSocket` のコネクションが開かれたときに発生します。

構文
--

イベント名を `addEventListener()` などのメソッドで使用するか、イベントハンドラープロパティを設定するかしてください。

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

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

イベント型
-----

一般的な `Event` です。

例
-

```js
// WebSocket の接続を作成
const socket = new WebSocket("ws://localhost:8080");

// 接続が開かれた場合
socket.addEventListener("open", (event) => {
  socket.send("Hello Server!");
});
```

仕様書
---

| Specification |
| --- |
| WebSockets Standard # dom-websocket-onopen |

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

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

関連情報
----

* WebSocket: close イベント
* WebSocket: error イベント
* WebSocket: message イベント
* WebSocket クライアントアプリケーションを書く


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

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

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

構文
--

```js
new WebSocket(url)
new WebSocket(url, protocols)
```

### 引数

`url`

接続先の URL です。この URL は WebSocket サーバーが応答するものでなければなりません。

`protocols` 省略可

単一のプロトコル文字列、またはプロトコル文字列の配列のいずれか。これらの文字列はサブプロトコルを示すために使用され、単一のサーバーで複数の WebSocket サブプロトコルを実装することもできます（たとえば、単一のサーバーで指定した `protocol` に応じて異なる種類のやりとりを処理できるようにしたい場合があります）。

省略された場合は、空配列、すなわち `[]` が既定で使用されます。

### 例外

`SyntaxError` `DOMException`

次のような場合に発生します。

* `url` の解釈に失敗した場合
* `url` のスキームが `ws` または `wss` 以外であった場合
* `url` にフラグメントがあった場合
* `protocols` の何れかの値が複数回現れている、または WebSocket プロトコル仕様で定義された `Sec-WebSocket-Protocol` (en-US) フィールドの値を構成する要素の要件に一致しない場合。

仕様書
---

| Specification |
| --- |
| WebSockets Standard # ref-for-dom-websocket-websocket① |

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

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

関連情報
----

* RFC 6455 （WebSocket プロトコル仕様書）


WebSocket: send() メソッド - Web API

WebSocket: send() メソッド
======================

**`WebSocket.send()`** メソッドは、 WebSocket 接続を介してサーバーに送るために指定されたデータを、格納するために必要なバイト数だけ `bufferedAmount` の値を増加させながらキューに入れます。もしデータが送信できなかった場合（例えば、バッファリングが必要だが、バッファが一杯であるなどの理由で）、ソケットは自動的に閉じられます。
 接続が `CONNECTING` 状態のときに `send()` を呼び出すと、ブラウザーは例外を発生させます。接続が `CLOSING` または `CLOSED` の状態のときに `send()` を呼び出すと、ブラウザーはデータを暗黙に破棄します。

構文
--

```js
send(data)
```

### 引数

`data`

サーバーに送信するデータです。以下の何れかの型のデータを指定します。

`string`

テキスト文字列。文字列は UTF-8 形式でバッファーに追加され、 `bufferedAmount` の値は UTF-8 の文字列を表すのに必要とされるバイト数だけ増えます。

`ArrayBuffer`

型付きの配列オブジェクトで使用される基本的なバイナリーデータを送信することができます。このバイナリーデータのコンテンツは，必要なバイト数だけ `bufferedAmount` の値を増やして、バッファーのキューに入れられます。

`Blob`

`Blob` を指定すると、バイナリーフレームで送信される blob の生データをキューに入れます（`Blob.type` は無視されます）。
 `bufferedAmount` の値は、その生データのバイトサイズだけ増えます。

`TypedArray` または `DataView`

JavaScript の型付き配列オブジェクトをバイナリーフレームとして送信することができます。このバイナリーデータのコンテンツは，必要なバイト数だけ `bufferedAmount` の値を増やして、バッファのキューに入れられます。

### 返値

なし (`undefined`)。

### 例外

`InvalidStateError` `DOMException`

`WebSocket.readyState` が `CONNECTING` である場合に発生します。

仕様書
---

| Specification |
| --- |
| WebSockets Standard # ref-for-dom-websocket-send① |

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

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


WebSocket: error イベント - Web API

WebSocket: error イベント
=====================

`error` イベントは、 `WebSocket` の接続がエラーによって閉じられた（例えば一部のデータを送信できなかった）ときに発生します。

構文
--

イベント名を `addEventListener()` などのメソッドで使用するか、イベントハンドラープロパティを設定するかしてください。

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

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

イベント型
-----

一般的な `Event` です。

例
-

```js
// WebSocket の接続を生成
const socket = new WebSocket("ws://localhost:8080");

// 発生しうるエラーを待ち受けする
socket.addEventListener("error", (event) => {
  console.log("WebSocket error: ", event);
});
```

仕様書
---

| Specification |
| --- |
| WebSockets Standard # dom-websocket-onerror |

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

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

関連情報
----

* WebSocket: close イベント
* WebSocket: message イベント
* WebSocket: open イベント
* WebSocket クライアントアプリケーションを書く


WebSocket: protocol プロパティ - Web API

WebSocket: protocol プロパティ
=========================

**`WebSocket.protocol`** は読み取り専用のプロパティで、サーバーが選択したサブプロトコル名を返します。これは `WebSocket` オブジェクトが作成されるときに、引数の `protocols` で指定された文字列のいずれかになりますが、接続が確立されていない場合は、空文字列となります。

値
-

文字列です。

仕様書
---

| Specification |
| --- |
| WebSockets Standard # ref-for-dom-websocket-protocol① |

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

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


WebSocket: readyState プロパティ - Web API

WebSocket: readyState プロパティ
===========================

**`WebSocket.readyState`** は読み取り専用のプロパティで、 `WebSocket` の「現在」の接続状態を返します。

値
-

以下のいずれかの `unsigned short` 値です。

| 値 | 状態 | 説明 |
| --- | --- | --- |
| `0` | `CONNECTING` | ソケットの作成が完了した。コネクションは開かれていない。 |
| `1` | `OPEN` | コネクションが開かれ、通信の準備ができている。 |
| `2` | `CLOSING` | コネクションが閉じる過程にある。 |
| `3` | `CLOSED` | コネクションが閉じられたか、開くことができなかった。 |

仕様書
---

| Specification |
| --- |
| WebSockets Standard # ref-for-dom-websocket-readystate① |

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

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


WebSocket: message イベント - Web API

WebSocket: message イベント
=======================

`message` イベントは、 `WebSocket` を通してデータを受け取ったときに発生します。

構文
--

イベント名を `addEventListener()` などのメソッドで使用するか、イベントハンドラープロパティを設定するかしてください。

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

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

イベント型
-----

`MessageEvent` です。 `Event` から継承しています。

Event

MessageEventイベントプロパティ
---------

*以下に示したプロパティに加え、親インターフェイスである `Event` から継承したプロパティも利用できます。*

`data` 読取専用

メッセージ送信者から送信されたデータです。このプロパティの型は、WebSocket メッセージの種類と `WebSocket.binaryType` の値によって変わります。

* メッセージの種類が "text" の場合、このフィールドは文字列です。
* メッセージの種類が "binary" 型の場合、このプロパティの型はこのソケットの `binaryType` から推測することができます。
    + `ArrayBuffer`: `binaryType` が `"arraybuffer"` の場合
    + `Blob`: `binaryType` が `"blob"` の場合、これは関連付けられたメディア型がありません（`Blob.type` は `""` です）.

`origin` 読取専用

文字列で、メッセージ送信者のオリジンを表します。

`MessageEvent` インターフェイスのその他のプロパティは存在しますが、 WebSocket API には関係ないため、既定値のままにしています。

* `lastEventId` 読取専用
* `source` 読取専用
* `ports` 読取専用
例
-

```js
// Create WebSocket connection.
const socket = new WebSocket("ws://localhost:8080");

// Listen for messages
socket.addEventListener("message", (event) => {
  console.log("Message from server ", event.data);
});
```

仕様書
---

| Specification |
| --- |
| WebSockets Standard # dom-websocket-onmessage |

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

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

関連情報
----

* WebSocket: close イベント
* WebSocket: error イベント
* WebSocket: open イベント
* WebSocket クライアントアプリケーションを書く


WebSocket: url プロパティ - Web API

WebSocket: url プロパティ
====================

**`WebSocket.url`** は読み取り専用のプロパティで、コンストラクターによって解決された `WebSocket` の絶対 URL を返します。

値
-

文字列です。

仕様書
---

| Specification |
| --- |
| WebSockets Standard # ref-for-dom-websocket-url① |

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

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


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

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

**`WebSocket.close()`** メソッドは、 `WebSocket` の接続、もしくは接続試行（存在した場合）を閉じます。接続がすでに `CLOSED` だった場合、このメソッドは何もしません。

**メモ:** 接続を閉じるプロセスはクロージングハンドシェイクで始まり、 `close()` メソッドはそのクロージングハンドシェイクを開始する前に以前に送信したメッセージを破棄しません。たとえユーザーエージェントがまだそれらのメッセージを送信するのに忙しい場合でも、ハンドシェイクはメッセージが送信されてから開始されます。

構文
--

```js
close()
close(code)
close(code, reason)
```

### 引数

`code` 省略可

整数の WebSocket 接続クローズコードの値で、閉じられた理由を示します。

* 指定されていない場合、接続のクローズコードが自動的に設定されます。通常のクローズの場合は `1000` に、そうでなければ `1001`-`1015` の範囲の他の標準値に、接続が閉じられた実際の理由を示すコードが設定されます。
* 指定された場合、この `code` 引数の値は、接続のためのクローズコードの自動設定を上書きし、代わりにカスタムコードを設定します。
 この値は整数でなければなりません。 `1000` か、あるいは `3000` から `4999` までの範囲で選択したカスタムコードでなければなりません。 `code` 値を指定する場合は、 `reason` 値も指定しなければなりません。

`reason` 省略可

独自の WebSocket 接続が閉じた理由を提供する文字列（閉じたことについて簡潔で人間が読める散文的な説明）。この値は 123 バイト以下でなければなりません（UTF-8 でエンコードされます）。

**メモ:** UTF-8 は 2 から 4 バイトを使用するため、 ASCII 以外の文字をエンコードすると、 123 文字の `reason` 値に ASCII 以外の文字が入っていると、 123 バイトの制限を超える可能性があります。

`reason` の値を指定する場合は、 `code` の値も指定してください。

### 返値

なし (`undefined`)。

### 例外

`InvalidAccessError` `DOMException`

`code` が `1000` と等しい整数でも、 `3000`–`4999` の範囲の整数でもない場合に発生します。

`SyntaxError` `DOMException`

UTF-8 でエンコードされた `reason` が 123 バイトよりも長かった場合。

仕様書
---

| Specification |
| --- |
| WebSockets Standard # ref-for-dom-websocket-close① |

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

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

関連情報
----

* RFC 6455 （WebSocket プロトコル仕様書）


WebSocket: close イベント - Web API

WebSocket: close イベント
=====================

`close` イベントは、 `WebSocket` の接続が閉じられたときに発生します。

構文
--

イベント名を `addEventListener()` などのメソッドで使用するか、イベントハンドラープロパティを設定するかしてください。

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

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

イベント型
-----

`CloseEvent` です。 `Event` から継承しています。

Event

CloseEventイベントプロパティ
---------

*下記に示したプロパティに加えて、親インターフェイスである `Event` からのプロパティが利用できます。*

`code` 読取専用

サーバーが送信したクローズコードを `unsigned short` で返します。

`reason` 読取専用

サーバーが接続を閉じた理由を示す文字列を返します。これは、特定のサーバーとサブプロトコルに固有のものです。

`wasClean` 読取専用

接続がきれいに閉じられたか否かを示す論理値を返します。

例
-

接続が閉じられる時が分かれば、 UI を更新させたり、閉じた接続についてのデータを保存したりすることができます。以下の例では `exampleSocket` と呼ばれる変数が開かれた `WebSocket` を参照しており、このハンドラーが、ソケットが閉じられた場面を扱います。

```js
exampleSocket.addEventListener("close", (event) => {
  console.log("The connection has been closed successfully.");
});
```

同じことを、イベントハンドラープロパティを用いて行うこともできます。

```js
exampleSocket.onclose = (event) => {
  console.log("The connection has been closed successfully.");
};
```

仕様書
---

| Specification |
| --- |
| WebSockets Standard # dom-websocket-onclose |

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

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

関連情報
----

* WebSocket: error イベント
* WebSocket: message イベント
* WebSocket: open イベント
* WebSocket クライアントアプリケーションを書く


WebSocket: bufferedAmount プロパティ - Web API

WebSocket: bufferedAmount プロパティ
===============================

**`WebSocket.bufferedAmount`** は読み取り専用のプロパティで、 `send()` の呼び出しによってキューに入れられてはいますが、まだネットワークに送信されていないデータのバイト数を返します。この値は、一度キューに入れられたデータすべてが送信されると 0 にリセットされます。なお、接続が閉じられたときは、 0 にリセットされません。 `send()` を呼び出し続けると、この値は大きくなっていきます。

値
-

`unsigned long` です。

仕様書
---

| Specification |
| --- |
| WebSockets Standard # ref-for-dom-websocket-bufferedamount① |

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

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


WebSocket: extensions プロパティ - Web API

WebSocket: extensions プロパティ
===========================

**`WebSocket.extensions`** は読み取り専用のプロパティで、サーバーによって選択された拡張機能を返します。現在は、空文字列か、接続によってネゴシエートされた拡張機能のリストのみを返します。

値
-

文字列です。

仕様書
---

| Specification |
| --- |
| WebSockets Standard # ref-for-dom-websocket-extensions① |

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

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


MessageChannel.port2 - Web API

MessageChannel.port2
====================

`MessageChannel` インターフェースの **`port2`** 読み取り専用プロパティは、メッセージチャンネルの第 2 ポートを返します。このポートは、チャンネルの元となるコンテキストに付属します。

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

構文
--
```

channel.port2;
```

### 値

チャンネルの第 2 ポートを表す `MessagePort` オブジェクト。これはチャンネルの元となるコンテキストに付属するポートです。

例
-

次のコードブロックでは、`MessageChannel.MessageChannel` コンストラクタを使用して作成された新しいチャンネルを知ることができます。`<iframe>` が読み込まれると、`MessagePort.postMessage` にメッセージを添えて `MessageChannel.port2` を `<iframe>` へ渡します。すると、`handleMessage` ハンドラが `<iframe>` から返送されたメッセージに (`MessagePort.onmessage` を使用して) 返答し、これを段落に挿入します。

```js
var channel = new MessageChannel();
var para = document.querySelector("p");

var ifr = document.querySelector("iframe");
var otherWindow = ifr.contentWindow;

ifr.addEventListener("load", iframeLoaded, false);

function iframeLoaded() {
  otherWindow.postMessage("Hello from the main page!", "\*", [channel.port2]);
}

channel.port1.onmessage = handleMessage;
function handleMessage(e) {
  para.innerHTML = e.data;
}
```

完全に動作する例は、Github 上の channel messaging basic demo を参照してください (実際のデモも実行できます)。

仕様
--

| Specification |
| --- |
| HTML Standard # dom-messagechannel-port2-dev |

ブラウザの実装状況
---------

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

関連情報
----

* Using channel messaging


MessageChannel() - Web API

MessageChannel()
================

`MessageChannel` インターフェースの `MessageChannel()` コンストラクタは、2 つの新しい `MessagePort` オブジェクトを持つ新しい `MessageChannel` オブジェクトを返します。

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

構文
--
```

var channel = new MessageChannel();
```

### 戻り値

新たに作成された `MessageChannel` オブジェクト。

例
-

次のコードブロックでは、`MessageChannel.MessageChannel` コンストラクタを使用して作成された新しいチャンネルを知ることができます。`<iframe>` が読み込まれると、`MessagePort.postMessage` にメッセージを添えて `MessageChannel.port2` を `<iframe>` へ渡します。すると、`handleMessage` ハンドラが `<iframe>` から返送されたメッセージに (`MessagePort.onmessage` を使用して) 返答し、これを段落に挿入します。

```js
var channel = new MessageChannel();
var para = document.querySelector("p");

var ifr = document.querySelector("iframe");
var otherWindow = ifr.contentWindow;

ifr.addEventListener("load", iframeLoaded, false);

function iframeLoaded() {
  otherWindow.postMessage("Hello from the main page!", "\*", [channel.port2]);
}

channel.port1.onmessage = handleMessage;
function handleMessage(e) {
  para.innerHTML = e.data;
}
```

完全に動作する例は、Github 上の channel messaging basic demo を参照してください (実際のデモも実行できます)。

仕様
--

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

ブラウザの実装状況
---------

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

関連情報
----

* Using channel messaging


MessageChannel.port1 - Web API

MessageChannel.port1
====================

**`port1`** は `MessageChannel` インターフェースの読み取り専用プロパティで、メッセージチャンネルの最初のポートを返します。このポートは、チャンネルの元となるコンテキストに付属します。

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

構文
--
```

channel.port1;
```

### 値

チャンネルの最初のポートを表す `MessagePort` オブジェクト。これはチャンネルの元となるコンテキストに付属するポートです。

例
-

次のコードブロックでは、 `MessageChannel()` コンストラクターを使用して作成された新しいチャンネルが見られます。 `<iframe>` が読み込まれると、 `MessageChannel.port2` を `<iframe>` へ、メッセージを通して `MessagePort.postMessage` を使用して渡します。すると、 `handleMessage` ハンドラーが `<iframe>` から返送されたメッセージに (`MessagePort.onmessage` を使用して) 返答し、これを段落に挿入します。メッセージが到着したとき、 `handleMessage` メソッドが `port1` に関連付けられて待ち受けします。

```js
var channel = new MessageChannel();
var para = document.querySelector("p");

var ifr = document.querySelector("iframe");
var otherWindow = ifr.contentWindow;

ifr.addEventListener("load", iframeLoaded, false);

function iframeLoaded() {
  otherWindow.postMessage("Hello from the main page!", "\*", [channel.port2]);
}

channel.port1.onmessage = handleMessage;
function handleMessage(e) {
  para.innerHTML = e.data;
}
```

仕様書
---

| Specification |
| --- |
| HTML Standard # dom-messagechannel-port1-dev |

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

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

関連情報
----

* Using channel messaging


Attr: ownerElement プロパティ - Web API

Attr: ownerElement プロパティ
========================

**`ownerElement`** は `Attr` インターフェイスの読み取り専用プロパティで、この属性が所属する要素 (`Element`) を返します。

値
-

この属性が所属する要素 (`Element`)、またはこの属性が要素に結びついていない場合は `null` です。

例
-

次の例では、適切なボタンをクリックすると、 2 つの最初の要素の要素の修飾名が表示されます。

### HTML コンテンツ

```html
<svg xml:lang="en-US" class="struct" height="1" width="1">Click me</svg>
<label xml:lang="en-US" class="struct"></label>

<p>
  <button>Show value for <svg></button>
  <button>Show value for <label></button>
</p>

<p>
  Qualified name of the owner element of the attribute <code>xml:lang</code>:
  <output id="result">None.</output>
</p>
```

### JavaScript コンテンツ

```js
const elements = document.querySelectorAll(".struct");
const buttons = document.querySelectorAll("button");
const outputEl = document.querySelector("#result");

let i = 0;
for (const button of buttons) {
  const element = elements[i];
  button.addEventListener("click", () => {
    const attribute = element.attributes[0];
    outputEl.value = attribute.ownerElement.tagName.toLowerCase();
  });
  i++;
}
```

### 結果

仕様書
---

| Specification |
| --- |
| DOM Standard # dom-attr-ownerelement |

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

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


Attr: localName プロパティ - Web API

Attr: localName プロパティ
=====================

**`localName`** は `Attr` インターフェイスのプロパティで、属性の*修飾名*の*ローカル部分*、すなわち属性の名前からその前の名前空間を外したものを返します。例えば、修飾名が `xml:lang` であった場合、要素が名前空間に対応していればローカル名は `lang` となります。

ローカル名は、属性の作成時に大文字であっても小文字であっても、常に小文字になります。

**メモ:** HTML は SVG と MathML の要素に対して、固定された一連の名前空間のみに対応しています。これらは `xml` （`xml:lang` 属性）、 `xlink` （`xlink:href`, `xlink:show`, `xlink:target`, `xlink:title` 属性）、`xpath` です。

つまり、 HTML 要素の属性のローカル名は常にその修飾名と等しくなります。コロンは通常の文字として扱われます。 XML では、 SVG や MathML のように、コロンは接頭辞の終わりを表し、それ以前は名前空間となります。ローカル名は、修飾名と異なる場合があります。

値
-

属性の修飾名のローカル部分を表す文字列です。

例
-

次の例では、適切なボタンをクリックすると、 2 つの最初の要素の最初の属性のローカル名が表示されます。 `<svg>` 要素は XML であり、名前空間に対応しているので、ローカル名 (`lang`) は修飾名 `xml:lang` と異なるものになります。 `<label>` 要素は HTML であり、名前空間に対応していないため、ローカル名と修飾名が共に `xml:lang` となります。

### HTML コンテンツ

```html
<svg xml:lang="en-US" class="struct" height="1" width="1">Click me</svg>
<label xml:lang="en-US" class="struct"></label>

<p>
  <button><svg> の場合の値を表示</button>
  <button><label> の場合の値を表示</button>
</p>

<p>
  <code>xml:lang</code> 属性のローカル部分:
  <output id="result">なし。</output>
</p>
```

### JavaScript コンテンツ

```js
const elements = document.querySelectorAll(".struct");
const buttons = document.querySelectorAll("button");
const outputEl = document.querySelector("#result");

let i = 0;
for (const button of buttons) {
  const element = elements[i];
  button.addEventListener("click", () => {
    const attribute = element.attributes[0];
    outputEl.value = attribute.localName;
  });
  i++;
}
```

### 結果

仕様書
---

| Specification |
| --- |
| DOM Standard # dom-attr-localname |

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

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

関連情報
----

* `Attr.name` プロパティはこの属性の修飾名を返し、 `Attr.prefix` は名前空間接頭辞を返します。
* `Element.localName()` プロパティは `Element` のローカル名を返します。


Attr: specified プロパティ - Web API

Attr: specified プロパティ
=====================

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

**`specified`** は `Attr` インターフェイスのプロパティで、常に `true` を返します。

値
-

常に `true` を返します。

仕様書
---

| Specification |
| --- |
| DOM Standard # dom-attr-specified |

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

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


Attr: name プロパティ - Web API

Attr: name プロパティ
================

**`name`** は `Attr` インターフェイスの読み取り専用プロパティで、属性の*修飾名*、すなわち属性名に、名前空間接頭辞があればそれが前に付いたものが返されます。例えば、ローカル名が `lang` で名前空間接頭辞が `xml` であった場合、返される修飾名は `xml:lang` になります。

修飾名は、属性が作成されたときの大文字小文字に関わらず、常に小文字になります。

値
-

この属性の修飾名を表す文字列です。

例
-

次の例では、適切なボタンをクリックすると、 2 つの最初の要素の最初の属性の修飾名が表示されます。

### HTML コンテンツ

```html
<svg xml:lang="en-US" class="struct" height="1" width="1">Click me</svg>
<label xml:lang="en-US" class="struct"></label>

<p>
  <button><svg> の場合の値を表示</button>
  <button><label> の場合の値を表示</button>
</p>

<p>
  <code>xml:lang</code> 属性の修飾名:
  <output id="result">なし。</output>
</p>
```

### JavaScript コンテンツ

```js
const elements = document.querySelectorAll(".struct");
const buttons = document.querySelectorAll("button");
const outputEl = document.querySelector("#result");

let i = 0;
for (const button of buttons) {
  const element = elements[i];
  button.addEventListener("click", () => {
    const attribute = element.attributes[0];
    outputEl.value = attribute.name;
  });
  i++;
}
```

### 結果

仕様書
---

| Specification |
| --- |
| DOM Standard # dom-attr-name |

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

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

関連情報
----

* `Attr.localName` プロパティはこの属性の修飾名のローカル名の部分を返し、 `Attr.prefix` は名前空間接頭辞を返します。
* `Element.tagName()` プロパティは `Element` の修飾名を返します。


Attr: namespaceURI プロパティ - Web API

Attr: namespaceURI プロパティ
========================

**`namespaceURI`** は `Attr` インターフェイスの読み取り専用プロパティで、この属性の名前空間 URI を返し、この要素が名前空間にない場合は `null` を返します。

 名前空間 URI は `Attr` の作成時に設定され、変更することができません。
 名前空間付きの属性は、 `Element.setAttributeNS()` で作成することができます。

**メモ:** 属性は、装着されている要素から名前空間を継承しません。
 属性に明示的に名前空間が与えられなかった場合は、名前空間なしになります。

ブラウザーは名前空間の検証そのものは行いませんし、強制もしません。必要な検証を行うのは JavaScript アプリケーションに任されています。また、名前空間接頭辞は一度特定の属性ノードに関連づけられると、変更することができないので注意してください。

値
-

文字列で、この属性の名前空間 URI が入ります。この要素が名前空間にない場合は `null` を返します。

例
-

 次の例は、HTML 要素と SVG 要素の場合で、接頭辞つきの属性の結果を示しています。
 HTML は名前空間を扱わないので、この場合、常に `null` を返します。
 SVG 要素の場合は、 XML の名前空間 URI である `http://www.w3.org/XML/1998/namespace` を返します。

### HTML コンテンツ

```html
<svg xml:lang="en-US" class="struct" height="1" width="1">Click me</svg>
<label xml:lang="en-US" class="struct"></label>

<p>
  <button><svg> の値を表示</button>
  <button><label> の値を表示</button>
</p>

<p>
  <code>xml:lang</code> 属性の名前空間 URI:
  <output id="result">なし。</output>
</p>
```

### JavaScript コンテンツ

```js
const elements = document.querySelectorAll(".struct");
const buttons = document.querySelectorAll("button");
const outputEl = document.querySelector("#result");

let i = 0;
for (const button of buttons) {
  const element = elements[i];
  button.addEventListener("click", () => {
    const attribute = element.attributes[0];
    outputEl.value = attribute.namespaceURI;
  });
  i++;
}
```

### 結果

仕様書
---

| Specification |
| --- |
| DOM Standard # dom-attr-namespaceuri |

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

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

関連情報
----

* `Attr.name` プロパティはこの属性の修飾名を返し、 `Attr.localName` プロパティはこの属性の修飾名のローカル名の部分を返し、 `Attr.prefix` は名前空間接頭辞を返します。
* `Element.namespaceURI` プロパティは `Element` について同等のものです。
* `Element.setAttributeNS()` メソッドは、指定された属性を指定された名前空間で作成します。


Attr: value プロパティ - Web API

Attr: value プロパティ
=================

**`value`** は `Attr` インターフェイスのプロパティで、この属性の値が入ります。

値
-

文字列で、この属性の値を表します。

例
-

次の例では、属性 `test` の現在の値を表示しています。ボタンをクリックすると別の値に変更され、再度読み込むと表示値が更新されます。

### HTML コンテンツ

```html
<label test="初期値"></label>

<button>クリックすると、test に <code>"新しい値"</code> を設定します。…</button>

<p>
  現在の <code>test</code> 属性の値:
  <output id="result">なし。</output>
</p>
```

### JavaScript コンテンツ

```js
const element = document.querySelector("label");
const button = document.querySelector("button");
const result = document.querySelector("#result");

const attribute = element.attributes[0];
result.value = attribute.value;

button.addEventListener("click", () => {
  attribute.value = "新しい値";
  result.value = attribute.value;
});
```

### 結果

仕様書
---

| Specification |
| --- |
| DOM Standard # dom-attr-value |

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

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


Attr: prefix プロパティ - Web API

Attr: prefix プロパティ
==================

**`prefix`** は `Attr` インターフェイスの読み取り専用プロパティで、この属性の名前空間接頭辞を返します。接頭辞が指定されていなければ `null` を返します。

接頭辞は、属性が作成されたときの大文字小文字に関わらず、常に小文字になります。

**メモ:** XML だけが名前空間に対応しています。 HTML は対応していません。つまり、 HTML 要素の属性の接頭辞は常に `null` になります。

また、`xml` （`xml:lang` 属性）、`xlink` （`xlink:href`, `xlink:show`, `xlink:target`, `xlink:title` 属性）、 `xpath` 名前空間だけに、 SVG と MathML 要素でのみ対応しています。

値
-

その属性が属する名前空間の接頭辞が入った文字列です。もしない場合は `null` を返します。

例
-

### HTML コンテンツ

```html
<svg xml:lang="en-US" class="struct" height="1" width="1">Click me</svg>
<label xml:lang="en-US" class="struct"></label>

<p>
  <button>Show value for <svg></button>
  <button>Show value for <label></button>
</p>

<p>
  Prefix of the attribute <code>xml:lang</code>:
  <output id="result">None.</output>
</p>
```

### JavaScript コンテンツ

```js
const elements = document.querySelectorAll(".struct");
const buttons = document.querySelectorAll("button");
const outputEl = document.querySelector("#result");

let i = 0;
for (const button of buttons) {
  const element = elements[i];
  button.addEventListener("click", () => {
    const attribute = element.attributes[0];
    outputEl.value = attribute.prefix;
  });
  i++;
}
```

### 結果

仕様書
---

| Specification |
| --- |
| DOM Standard # dom-attr-prefix |

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

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

関連情報
----

* `Attr.name` プロパティはこの属性の修飾名を返し、 `Attr.localName` プロパティはこの属性の修飾名のローカル名の部分を返します。
* `Element.prefix()` プロパティは `Element` の名前空間接頭辞を返します。


LockManager: query() メソッド - Web API

LockManager: query() メソッド
=========================

`LockManager` インターフェイスの **`query()`** メソッドは、確保中のロックと獲得待ち中のロックに関する情報を持ったオブジェクトで解決する `Promise` を返します。

構文
--

```js
query()
```

### 引数

なし

### 返値

`LockManager` の状態のスナップショットを持ったオブジェクトで解決する `Promise` を返します。このオブジェクトは以下のプロパティを持ちます。

* `held`: 確保中のロックに関する `LockInfo` オブジェクトの配列です。
* `pending`: 獲得待ち中のロックに関する `LockInfo` オブジェクトの配列です。
### 例外

このメソッドは、以下のいずれかの種類の `DOMException` で拒否される `Promise` を返す可能性があります。

`InvalidStateError` `DOMException`

ドキュメントが完全にアクティブでない環境のとき投げられます。

`SecurityError` `DOMException`

現在の環境でロックマネージャーが取得できないとき投げられます。

例
-

```js
const state = await navigator.locks.query();
for (const lock of state.held) {
  console.log(`確保中のロック: 名前 ${lock.name}, モード ${lock.mode}`);
}
for (const request of state.pending) {
  console.log(`要求中のロック: 名前 ${request.name}, モード ${request.mode}`);
}
```

仕様書
---

| Specification |
| --- |
| Web Locks API # api-lock-manager-query |

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

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


LockManager: request() メソッド - Web API

LockManager: request() メソッド
===========================

`LockManager` インターフェイスの **`request()`** メソッドは、名前と性質を指定する引数をとり、`Lock` オブジェクトを要求します。要求された `Lock` はコールバックに渡されます。この関数自体は、ロックの解放後にコールバックの結果で解決 (または拒否) され、リクエストが中止された場合は拒否される `Promise` を返します。

引数 `options` のプロパティ `mode` は、`"exclusive"` と `"shared"` のいずれかをとることができます。

一度に 1 個のコードインスタンスのみがロックを確保するべきときは、`"exclusive"` ロックを要求します。これはタブで実行するコードにもワーカーで実行するコードにも当てはまります。これはリソースへの互いに排他的なアクセスを表します。ある名前の `"exclusive"` ロックが確保されているときは、同じ名前の他のロックは一切確保できません。

コードの複数のインスタンスがリソースへのアクセスを共有できるときは、`"shared"` ロックを要求します。ある名前の `"shared"` ロックが確保されているときは、同じ名前の他の `"shared"` ロックを獲得することはできますが、その名前の `"exclusive"` ロックを獲得・確保することができません。

この共有 / 排他ロックのパターンは、読み込みは同時に複数 (それぞれが `"shared"` ロックを要求する) 行うことを許し、書き込みは 1 個だけ (単一の `"exclusive"` ロック) 許すなど、データベースのトランザクションのアーキテクチャではよくみられます。これは readers-writer パターンとして知られています。IndexedDB API では、これは同じ意味の `"readonly"` および `"readwrite"` トランザクションとして公開されています。

構文
--

```js
request(name, callback)
request(name, options, callback)
```

### 引数

`name`

要求するロックの識別子です。

`options` 省略可

生成するロックの性質を記述するオブジェクトです。以下の値が有効です。

`mode` 省略可

`"exclusive"` または `"shared"` です。デフォルト値は `"exclusive"` です。

`ifAvailable` 省略可

`true` に設定した場合、ロックが既に確保されていない場合のみロックを獲得できます。ロックを獲得できない場合は、コールバックには `Lock` のインスタンスではなく `null` が渡されます。デフォルト値は `false` です。

`steal` 省略可

`true` に設定した場合、同じ名前の既に確保されているロックはすべて解放され、待機中のすべての要求よりも優先してロックを獲得します。デフォルト値は `false` です。

**警告:** 使用には注意が必要です！
 これまでロック内で実行されていたコードの実行は継続し、新しくロックを確保したコードと衝突する可能性があります。

`signal` 省略可

`AbortSignal` (`AbortController` の `signal` プロパティ) です。指定され、対応する `AbortController` が中断された場合、獲得できていないロックの要求は破棄されます。

`callback`

ロックを獲得したとき呼び出されるメソッドです。ロックはコールバックから返ったとき (または例外が投げられたとき) 自動的に解放されます。通常、コールバックは非同期関数で、この場合はロックは非同期の実行が完全に完了するまで解放されません。

### 返値

ロックの解放後コールバックの結果で解決 (または拒否) し、要求が中断されると拒否される `Promise` を返します。

### 例外

このメソッドは、以下のいずれかの種類の `DOMException` で拒否される `Promise` を返す可能性があります。

`InvalidStateError` `DOMException`

ドキュメントが完全にアクティブでない環境のとき。

`SecurityError` `DOMException`

現在の環境でロックマネージャーが取得できないとき。

`NotSupportedError` `DOMException`

`name` がハイフン (`-`) で始まるとき、`steal` と `ifAvailable` の両方が `true` に設定されているとき、`signal` が設定されておりかつ `steal` と `ifAvailable` の *いずれか* が `true` に設定されているとき。

`AbortError` `DOMException`

`signal` が設定されており、中断されたとき。

例
-

### 一般の例

以下の例では、非同期関数をコールバックとして用いる `request()` メソッドの基本的な使用法を示します。コールバックが呼び出されると、それが帰るまでこのオリジンで実行中の他のコードは `my_resource` を確保できません。

```js
await navigator.locks.request("my\_resource", async (lock) => {
  // ロックを確保した
});
```

### モードの例

以下の例では、リーダーとライターがどのように `mode` を用いるかを示します。

両方の関数が `my_resource` というロックを用いることに注意してください。`do_read()` は `'shared'` モードでロックを要求します。これは、異なるイベントハンドラー・タブ・ワーカーが同時に呼び出せるということです。

```js
async function do\_read() {
  await navigator.locks.request(
    "my\_resource",
    { mode: "shared" },
    async (lock) => {
      // ここで読み込みを行う
    },
  );
}
```

`do_write()` 関数は、同じロックを `'exclusive'` モードで用います。これは、書き込み操作が完了するまで `do_read()` 関数内の `request()` の呼び出しを遅らせます。これはイベントハンドラー・タブ・ワーカーにまたがって適用されます。

```js
async function do\_write() {
  await navigator.locks.request(
    "my\_resource",
    { mode: "exclusive" },
    async (lock) => {
      // ここで書き込みを行う
    },
  );
}
```

### ifAvailable の例

既に確保されていないときのみロックを獲得するには、`ifAvailable` オプションを用います。この関数では、`await` によりメソッドをコールバックが完了するまで帰らないようにしています。ロックは利用可能なときのみ獲得できるので、この呼び出しはロックが他のどこかで解放されるのを待たずにすみます。

```js
await navigator.locks.request(
  "my\_resource",
  { ifAvailable: true },
  async (lock) => {
    if (!lock) {
      // ロックが獲得できなかったので、早期脱出する
      return;
    }

    // ロックが獲得できた。このオリジンで実行中の他のコードは
    // このコードが帰るまで 'my\_res\_lock' ロックを確保できない。
  },
);
```

### signal の例

短時間のみロックを待機するには、`signal` オプションを用います。

```js
const controller = new AbortController();
// 200ms まで待つ
setTimeout(() => controller.abort(), 200);

try {
  await navigator.locks.request(
    "my\_resource",
    { signal: controller.signal },
    async (lock) => {
      // ロックが獲得できた！
    },
  );
} catch (ex) {
  if (ex.name === "AbortError") {
    // ロックの獲得前に要求が中断された
  }
}
```

仕様書
---

| Specification |
| --- |
| Web Locks API # api-lock-manager-request |

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

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


CanvasRenderingContext2D.moveTo() - Web API

CanvasRenderingContext2D.moveTo()
=================================

**`CanvasRenderingContext2D.moveTo()`** はキャンバス 2D API のメソッドで、新しいサブパスの始点を `(x, y)` 座標に移動します。

構文
--

```js
void ctx.moveTo(x, y);
```

### 引数

`x`

点の x (水平) 座標。

`y`

点の y (鉛直) 座標。

例
-

### 複数のサブパスの作成

この例は、`moveTo()` を使用して、1 つのパス内に 2 つのサブパスを作成します。サブパスは両方とも `stroke()` の呼び出し 1 回で、描画することができます。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

最初の線は、 (50, 50) が始点で (200, 50) が終点です。 2 番目の線は、(50, 90) が始点で (280, 120) が終点です。

```js
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");

ctx.beginPath();
ctx.moveTo(50, 50); // 1 つ目のサブパス
ctx.lineTo(200, 50);
ctx.moveTo(50, 90); // 2 つ目のサブパス
ctx.lineTo(280, 120);
ctx.stroke();
```

#### 結果

仕様書
---

| Specification |
| --- |
| HTML Standard # dom-context-2d-moveto-dev |

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

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

関連情報
----

* このメソッドを定義しているインターフェイス: `CanvasRenderingContext2D`
* `CanvasRenderingContext2D.lineTo()`
* `CanvasRenderingContext2D.stroke()`


CanvasRenderingContext2D.direction - Web API

CanvasRenderingContext2D.direction
==================================

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

**`CanvasRenderingContext2D.direction`** はキャンバス 2D API のプロパティで、テキストを描画する際に使用する現在の書字方向を指定します。

構文
--

```js
ctx.direction = "ltr" || "rtl" || "inherit";
```

### オプション

指定可能な値は下記の通りです。

`"ltr"`

テキストの書字方向を左書き (left-to-right) にします。

`"rtl"`

テキストの書字方向を右書き (right-to-left) にします。

`"inherit"`

テキストの書字方向を `<canvas>` 要素または `Document` から適宜継承します。既定値です。

既定値は `"inherit"` です。

例
-

### 書字方向の変更

この例では、 2 つのテキストを描画しています。最初のものは左から右へ、 2 番目は右から左へ描画します。`ltr` の "Hi!" は `rtl` では "!Hi" になることに注意してください。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

```js
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");

ctx.font = "48px serif";
ctx.fillText("Hi!", 150, 50);
ctx.direction = "rtl";
ctx.fillText("Hi!", 150, 130);
```

#### 結果

仕様書
---

| Specification |
| --- |
| HTML Standard # dom-context-2d-direction-dev |

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

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

関連情報
----

* このメソッドを定義するインターフェイスである `CanvasRenderingContext2D`


CanvasRenderingContext2D: fillText() メソッド - Web API

CanvasRenderingContext2D: fillText() メソッド
=========================================

`CanvasRenderingContext2D` の **`fillText()`** はキャンバス 2D API のメソッドで、指定した座標にテキスト文字列を描画し、その文字を現在の `fillStyle` で塗りつぶします。オプションの引数で、描画されるテキストの最大幅を指定すると、ユーザーエージェントは、この幅に収まるようにテキストを圧縮したり、フォントサイズを縮小したりします。

このメソッドは現在のパスを変更することなく直接描画を行うため、その後の `fill()` (en-US) や `stroke()` の呼び出しには影響を与えません。

テキストのフォントやレイアウト構成は、 `font`、`textAlign`、`textBaseline`、`direction` の各プロパティで定義されたものを使用して描画が行われます。

**メモ:** 文字列の文字の輪郭を描画するには、そのコンテキストで `strokeText()` メソッドを呼び出してください。

構文
--

```js
fillText(text, x, y)
fillText(text, x, y, maxWidth)
```

### 引数

`text`

文字列で、このコンテキストに描画するテキスト文字列を指定します。テキストは、 `font`、`textAlign`、`textBaseline`、`direction` の設定を使用して描画されます。

`x`

テキストの描画を始める、x 軸の座標をピクセル単位で指定します。

`y`

テキストの描画を始める、y 軸の座標をピクセル単位で指定します。

`maxWidth` 省略可

描画するテキストの最大幅をピクセル数で指定します。指定しなかった場合、テキストの幅は制限されません。この値を指定すると、ユーザーエージェントはカーニングを調整したり、水平方向に縮小されたフォントを選択したり（利用可能であるか、または品質を損なうことなく生成できる場合）、フォントを縮小したりして、指定した幅にテキストを収めます。

### 返値

なし (`undefined`)。

例
-

### 塗りつぶしたテキストを描画

この例では、 "Hello world" という語を `fillText()` メソッドで描画します。

#### HTML

まず、描画するためのキャンバスが必要です。このコードでは、幅 400 ピクセル、横 150 ピクセルのコンテキストを作成します。

```html
<canvas id="canvas" width="400" height="150"></canvas>
```

#### JavaScript

この例の JavaScript コードは次のようになります。

```js
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

ctx.font = "50px serif";
ctx.fillText("Hello world", 50, 90);
```

このコードでは、 `<canvas>` への参照を取得し、その 2D グラフィックコンテキストへの参照を取得します。

そして、 `font` を高さ 50 ピクセルの "serif" （ユーザーの既定のセリフ付きフォント）に設定し、 `fillText()` を呼び出して座標 (50, 90) からテキスト "Hello world" を描画しています。

#### 結果

### テキストの大きさの制限

この例は "Hello world" という文字列を、 140 ピクセルの幅に制約して描画します。

#### HTML

```html
<canvas id="canvas" width="400" height="150"></canvas>
```

#### JavaScript

```js
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

ctx.font = "50px serif";
ctx.fillText("Hello world", 50, 90, 140);
```

#### 結果

仕様書
---

| Specification |
| --- |
| HTML Standard # dom-context-2d-filltext-dev |

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

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

関連情報
----

* テキストの描画
* `CanvasRenderingContext2D`
* `CanvasRenderingContext2D.strokeText()`


CanvasRenderingContext2D.arcTo() - Web API

CanvasRenderingContext2D.arcTo()
================================

**`CanvasRenderingContext2D.arcTo()`** はキャンバス 2D APIのメソッドで、制御点と半径を指定して現在のサブパスに円弧を追加します。円弧は、指定された引数で必要に応じて、パスの最後の点に自動的に直線で接続されます。

このメソッドは、主に角丸の図形を描画するのに使用されます。

**メモ:** 相対的に大きな半径を指定した場合、得られる角丸の描線が期待するものとは異なる可能性があります。円弧と連結する直線は円弧の半径に合うように描線されます。

構文
--

```js
void ctx.arcTo(x1, y1, x2, y2, radius);
```

### 引数

`x1`

1 つ目の制御点の x 座標。

`y1`

1 つ目の制御点の y 座標。

`x2`

2 つ目の制御点の x 座標。

`y2`

2 つ目の制御点の y 座標。

`radius`

円弧の半径。負でない値を設定する必要があります。

結果
--

### arcTo の動作

`arcTo()` の動作を解釈するには、始点と 1 つ目の制御点を結ぶ直線と、そこから 2 つ目の制御点を結ぶ直線の 2 つの線をイメージする方法があります。 `arcTo()` を使用しない場合、これら 2 つの線分は鋭角を形成しますが、 `arcTo()` はこの鋭角部分に接する円弧を描くことで滑らかに接続します。すなわち、 2 つの直線に接する円弧を作成することになります。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

```js
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

// 補助線
ctx.beginPath();
ctx.strokeStyle = "gray";
ctx.moveTo(200, 20);
ctx.lineTo(200, 130);
ctx.lineTo(50, 20);
ctx.stroke();

// 円弧
ctx.beginPath();
ctx.strokeStyle = "black";
ctx.lineWidth = 5;
ctx.moveTo(200, 20);
ctx.arcTo(200, 130, 50, 20, 40);
ctx.stroke();

// 開始点
ctx.beginPath();
ctx.fillStyle = "blue";
ctx.arc(200, 20, 5, 0, 2 \* Math.PI);
ctx.fill();

// 制御点
ctx.beginPath();
ctx.fillStyle = "red";
ctx.arc(200, 130, 5, 0, 2 \* Math.PI); // Control point one
ctx.arc(50, 20, 5, 0, 2 \* Math.PI); // Control point two
ctx.fill();
```

#### 結果

この例では、 `arcTo()` によって描かれる線を**黒い太線**を描きます。補助線は灰色、制御点は赤、開始点は青です。

### 角丸図形の作成

この例では `arcTo()`を用いて丸い角を持つ線を描画しています。これが最も一般的な使われ方です。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

描線は直前の `moveTo()` により座標 (230, 20) から開始し、 2 つの制御点 (90, 130) と (20, 20) を結ぶ直線に接するように形成された半径 50 の円弧に接続されます。円弧の終端からは `lineTo()` メソッドにより (20, 20) の点まで直線が描画されます。 2 つ目の制御点の座標と同じ座標を `lineTo()` で指定することで、より滑らかな描線を得ることができます。

```js
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const p0 = { x: 230, y: 20 };
const p1 = { x: 90, y: 130 };
const p2 = { x: 20, y: 20 };

const labelPoint = function (p) {
  const offset = 15;
  ctx.fillText("(" + p.x + "," + p.y + ")", p.x + offset, p.y + offset);
};

ctx.beginPath();
ctx.moveTo(p0.x, p0.y);
ctx.arcTo(p1.x, p1.y, p2.x, p2.y, 50);
ctx.lineTo(p2.x, p2.y);

labelPoint(p0);
labelPoint(p1);
labelPoint(p2);

ctx.stroke();
```

#### 結果

### 大きすぎる半径を指定した場合

相対的に大きな半径を指定した場合には、前述の方法では期待されるような滑らかな描線は得られません。この例では、 `moveTo()` 後の地点から円弧に接続される線は下方ではなく上方に向かってしまっています。これは、 2 つの直線に接する円の半径が大き過ぎるために、始点よりも上方に円弧との接点があるために発生しています。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

```js
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

ctx.beginPath();
ctx.moveTo(180, 90);
ctx.arcTo(180, 130, 110, 130, 130);
ctx.lineTo(110, 130);
ctx.stroke();
```

#### 結果

### ライブデモ

以下はより洗練されたデモです。半径の変化幅を調節し、どのように描線が変化するかを試すことができます。

#### HTML

```html
<div>
  <label for="radius">Radius: </label>
  <input name="radius" type="range" id="radius" min="0" max="100" value="50" />
  <label for="radius" id="radius-output">50</label>
</div>
<canvas id="canvas"></canvas>
```

#### JavaScript

```js
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

const controlOut = document.getElementById("radius-output");
const control = document.getElementById("radius");
control.oninput = () => {
  controlOut.textContent = r = control.value;
};

const mouse = { x: 0, y: 0 };

let r = 100; // Radius
const p0 = { x: 0, y: 50 };

const p1 = { x: 100, y: 100 };
const p2 = { x: 150, y: 50 };
const p3 = { x: 200, y: 100 };

const labelPoint = function (p, offset, i = 0) {
  const { x, y } = offset;
  ctx.beginPath();
  ctx.arc(p.x, p.y, 2, 0, Math.PI \* 2);
  ctx.fill();
  ctx.fillText(`${i}:(${p.x}, ${p.y})`, p.x + x, p.y + y);
};

const drawPoints = function (points) {
  for (let i = 0; i < points.length; i++) {
    var p = points[i];
    labelPoint(p, { x: 0, y: -20 }, i);
  }
};

// Draw arc
const drawArc = function ([p0, p1, p2], r) {
  ctx.beginPath();
  ctx.moveTo(p0.x, p0.y);
  ctx.arcTo(p1.x, p1.y, p2.x, p2.y, r);
  ctx.lineTo(p2.x, p2.y);
  ctx.stroke();
};

let t0 = 0;
let rr = 0; // the radius that changes over time
let a = 0; // angle
let PI2 = Math.PI \* 2;
const loop = function (t) {
  t0 = t / 1000;
  a = t0 % PI2;
  rr = Math.abs(Math.cos(a) \* r);

  ctx.clearRect(0, 0, canvas.width, canvas.height);

  drawArc([p1, p2, p3], rr);
  drawPoints([p1, p2, p3]);
  requestAnimationFrame(loop);
};

loop(0);
```

#### 結果

仕様書
---

| Specification |
| --- |
| HTML Standard # dom-context-2d-arcto-dev |

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

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

関連情報
----

* このメソッドを定義しているインターフェイス: `CanvasRenderingContext2D`


CanvasRenderingContext2D.drawFocusIfNeeded() - Web API

CanvasRenderingContext2D.drawFocusIfNeeded()
============================================

**`CanvasRenderingContext2D.drawFocusIfNeeded()`** はキャンバス 2D API のメソッドで、引数で与えられた要素にフォーカスが当たった時に、現在のパスもしくは指定されたパスの周りにフォーカスリングを描画します。

構文
--

```js
void ctx.drawFocusIfNeeded(element);
void ctx.drawFocusIfNeeded(path, element);
```

### 引数

element

フォーカスしたかどうかをチェックする要素。

`path`

利用する `Path2D` (en-US) パス。

例
-

### ボタンのフォーカスの管理

この例では、キャンバス上に 2 つのボタンを描画します。 `drawFocusIfNeeded()` メソッドは、必要に応じてフォーカスリングを描画するために使用されます。

#### HTML

```html
<canvas id="canvas">
  <button id="button1">続ける</button>
  <button id="button2">終了</button>
</canvas>
```

#### JavaScript

```js
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const button1 = document.getElementById("button1");
const button2 = document.getElementById("button2");

document.addEventListener("focus", redraw, true);
document.addEventListener("blur", redraw, true);
canvas.addEventListener("click", handleClick, false);
redraw();

function redraw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  drawButton(button1, 20, 20);
  drawButton(button2, 20, 80);
}

function handleClick(e) {
  // Calculate click coordinates
  const x = e.clientX - canvas.offsetLeft;
  const y = e.clientY - canvas.offsetTop;

  // 必要に応じて button1 をフォーカスする
  drawButton(button1, 20, 20);
  if (ctx.isPointInPath(x, y)) {
    button1.focus();
  }

  // 必要に応じて button2 をフォーカスする
  drawButton(button2, 20, 80);
  if (ctx.isPointInPath(x, y)) {
    button2.focus();
  }
}

function drawButton(el, x, y) {
  const active = document.activeElement === el;
  const width = 150;
  const height = 40;

  // ボタンの背景
  ctx.fillStyle = active ? "pink" : "lightgray";
  ctx.fillRect(x, y, width, height);

  // ボタンのテキスト
  ctx.font = "15px sans-serif";
  ctx.textAlign = "center";
  ctx.textBaseline = "middle";
  ctx.fillStyle = active ? "blue" : "black";
  ctx.fillText(el.textContent, x + width / 2, y + height / 2);

  // クリック可能な領域を定義
  ctx.beginPath();
  ctx.rect(x, y, width, height);

  // 必要に応じてフォーカスリングを描画
  ctx.drawFocusIfNeeded(el);
}
```

#### 結果

仕様書
---

| Specification |
| --- |
| HTML Standard # dom-context-2d-drawfocusifneeded-dev |

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

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

関連情報
----

* このメソッドを定義しているインターフェイス: `CanvasRenderingContext2D`


CanvasRenderingContext2D.rect() - Web API

CanvasRenderingContext2D.rect()
===============================

**`CanvasRenderingContext2D.rect()`** はキャンバス 2D API のメソッドで、現在のパスに矩形を追加します。

現在のパスを変更する他のメソッドと同様に、このメソッドも直接何かを描画するわけではありません。 矩形をキャンバスに描画するには、 `fill()` (en-US) または `stroke()` メソッドを使用することができます。

**メモ:** 矩形の作成とレンダリングを一度に行うには、 `fillRect()` または `strokeRect()` メソッドを使用してください。

構文
--

```js
void ctx.rect(x, y, width, height);
```

`rect()` メソッドは、 `(x, y)` を始点とし、 `width` と `height` で大きさを指定した矩形のパスを作成します。

### 引数

`x`

矩形の開始位置の X 座標です。

`y`

矩形の開始位置の Y 座標です。

`width`

矩形の幅です。正の値の場合は右側に、負の値の場合は左側になります。

`height`

矩形の高さです。正の値の場合は下側に、負の値の場合は上側になります。

例
-

### 矩形を描画

この例は、矩形のパスを `rect()` メソッドを使用して生成します。このパスは `fill()` メソッドをし擁して描画されます。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

矩形の角は (10, 20) の位置です。幅は 150 で高さは 100 です。

```js
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
ctx.rect(10, 20, 150, 100);
ctx.fill();
```

#### 結果

仕様書
---

| Specification |
| --- |
| HTML Standard # dom-context-2d-rect-dev |

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

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

関連情報
----

* このメソッドを定義しているインターフェイス: `CanvasRenderingContext2D`
* `CanvasRenderingContext2D.fillRect`
* `CanvasRenderingContext2D.strokeRect()`
* `CanvasRenderingContext2D.fill()` (en-US)
* `CanvasRenderingContext2D.stroke()`


CanvasRenderingContext2D.setLineDash() - Web API

CanvasRenderingContext2D.setLineDash()
======================================

**`setLineDash()`** はキャンバス 2D API の `CanvasRenderingContext2D` インターフェイスのメソッドで、線を描画するときに使用される線の模様を設定します。 これは描画する線とその隙間の長さの値を交互に指定する配列を使用します。

**メモ:** 線の模様を実線に戻す場合には、指定する配列の中身を空にします。

構文
--

```js
ctx.setLineDash(segments);
```

### 引数

`segments`

(`Array`) で、描画する線の長さとその隙間の数値を交互に指定する配列 (座標空間単位)。配列内の要素数が奇数の場合、配列の要素がコピーされて連結されます。 例えば、`[5, 15, 25]`は`[5, 15, 25, 5, 15, 25]`になります。配列が空の場合、ラインダッシュリストはリセットされ、描画される線は実線に戻ります。

### 返値

`undefined` です。

例
-

### 基本的な例

この例では、`setLineDash()`メソッドを使用して、実線の上に破線を描画します。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

```js
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

// Dashed line
ctx.beginPath();
ctx.setLineDash([5, 15]);
ctx.moveTo(0, 50);
ctx.lineTo(300, 50);
ctx.stroke();

// Solid line
ctx.beginPath();
ctx.setLineDash([]);
ctx.moveTo(0, 100);
ctx.lineTo(300, 100);
ctx.stroke();
```

#### 結果

### いくつかの一般的な模様

この例は、さまざまな一般的な破線のパターンを示しています。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

下記の `drawDashedLine()` 関数を使用すると、複数の破線を簡単に描画できます。引数としてパターン配列を受け取ります。

```js
function drawDashedLine(pattern) {
  ctx.beginPath();
  ctx.setLineDash(pattern);
  ctx.moveTo(0, y);
  ctx.lineTo(300, y);
  ctx.stroke();
  y += 20;
}

const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
let y = 15;

drawDashedLine([]);
drawDashedLine([1, 1]);
drawDashedLine([10, 10]);
drawDashedLine([20, 5]);
drawDashedLine([15, 3, 3, 3]);
drawDashedLine([20, 3, 3, 3, 3, 3, 3, 3]);
drawDashedLine([12, 3, 3]); // [12, 3, 3, 12, 3, 3] と同じ
```

#### 結果

仕様書
---

| Specification |
| --- |
| HTML Standard # dom-context-2d-setlinedash-dev |

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

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

関連情報
----

* このメソッドを定義しているインターフェイス: `CanvasRenderingContext2D`
* `CanvasRenderingContext2D.getLineDash()` (en-US)
* `CanvasRenderingContext2D.lineDashOffset` (en-US)


CanvasRenderingContext2D.lineCap - Web API

CanvasRenderingContext2D.lineCap
================================

**`CanvasRenderingContext2D.lineCap`** はキャンバス 2D API のプロパティで、描く線の端点の形状を設定します。

**メモ:** 線は `stroke()`、`strokeRect()`、`strokeText()` の各メソッドで描画されます。

構文
--

```js
ctx.lineCap = "butt" || "round" || "square";
```

### オプション

`"butt"`

端点が四角く切られます。既定値です。

`"round"`

端点が丸くなります。

`"square"`

端点は、線の太さと同じ幅、半分の高さのボックスが追加されて四角くなります。

例
-

### 線の先端の形を変える

この例では直線の端点を丸めています。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

```js
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

ctx.beginPath();
ctx.moveTo(20, 20);
ctx.lineWidth = 15;
ctx.lineCap = "round";
ctx.lineTo(100, 100);
ctx.stroke();
```

#### 結果

### 先端形状の比較

次の例では、`lineCap` プロパティがそれぞれ異なる 3 本の線を描画しています。その違いを観察するために、 2 本の補助線を引いています。 3 本の線はそれぞれこの補助線直上を始点および終点として描かれています。

左の線は既定のオプションである `"butt"` の場合の線で、補助線のところで丁度切れています。 2 つ目の`"round"` オプションの場合の線は、補助線の部分の先に半円が追加された格好になっています。右側の`"square"` オプションによる描線は、線の幅と同じ幅で高さが半分の四角形が追加されています。
```

<canvas id="canvas" width="150" height="150"></canvas>
```

```js
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const lineCap = ["butt", "round", "square"];

// Draw guides
ctx.strokeStyle = "#09f";
ctx.beginPath();
ctx.moveTo(10, 10);
ctx.lineTo(140, 10);
ctx.moveTo(10, 140);
ctx.lineTo(140, 140);
ctx.stroke();

// Draw lines
ctx.strokeStyle = "black";
for (let i = 0; i < lineCap.length; i++) {
  ctx.lineWidth = 15;
  ctx.lineCap = lineCap[i];
  ctx.beginPath();
  ctx.moveTo(25 + i \* 50, 10);
  ctx.lineTo(25 + i \* 50, 140);
  ctx.stroke();
}
```

| Screenshot | Live sample |
| --- | --- |
|  |  |

仕様書
---

| Specification |
| --- |
| HTML Standard # dom-context-2d-linecap-dev |

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

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

### WebKit/Blink 特有のメモ

* WebKit および Blink ベースのブラウザーでは、このプロパティに加えて標準外で非推奨のメソッド `ctx.setLineCap()` が実装されています。
関連情報
----

* The interface defining this property: `CanvasRenderingContext2D`
* `CanvasRenderingContext2D.lineWidth` (en-US)
* `CanvasRenderingContext2D.lineJoin` (en-US)
* スタイルと色の適用


CanvasRenderingContext2D.save() - Web API

CanvasRenderingContext2D.save()
===============================

**`CanvasRenderingContext2D.save()`** はキャンバス 2D API のメソッドで、現在の状態をスタックにプッシュすることで、キャンバス全体の状態を保存します。

### 描画状態

スタックに保存される描画状態には、以下のものが含まれます。

* 現在の変形行列。
* 現在のクリッピング領域。
* 現在の点線リスト。
* `strokeStyle`、 `fillStyle`、`globalAlpha`、`lineWidth` (en-US)、`lineCap`、`lineJoin` (en-US)、`miterLimit` (en-US)、`lineDashOffset` (en-US)、`shadowOffsetX`、`shadowOffsetY`、`shadowBlur`、`shadowColor`、`globalCompositeOperation`、`font`、`textAlign`、`textBaseline`、`direction`、`imageSmoothingEnabled` の現在の値。
構文
--

```js
void ctx.save();
```

例
-

### 描画状態の保存

この例は、`save()` メソッドを使用して既定の状態を保存し、 `restore()` を使用して復元しているため、既定の状態で長方形を描画できます。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

```js
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

// 既定の状態を保存
ctx.save();

ctx.fillStyle = "green";
ctx.fillRect(10, 10, 100, 100);

// 既定の状態を復元
ctx.restore();

ctx.fillRect(150, 40, 100, 100);
```

#### 結果

仕様書
---

| Specification |
| --- |
| HTML Standard # dom-context-2d-save-dev |

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

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

関連情報
----

* このメソッドを定義しているインターフェイス: `CanvasRenderingContext2D`
* `CanvasRenderingContext2D.restore()` (en-US)


CanvasRenderingContext2D: putImageData() メソッド - Web API

CanvasRenderingContext2D: putImageData() メソッド
=============================================

Canvas 2D API の **`CanvasRenderingContext2D.putImageData()`** メソッドは、指定の `ImageData` オブジェクトのデータをキャンバスに描画します。更新対象の矩形が指定された場合は、その矩形内のピクセルのみが描画されます。このメソッドは、キャンバスの変換行列の影響を受けません。

**メモ:** `getImageData()` メソッドを用いて、キャンバスから画像データを取得できます。

記事キャンバスとピクセル操作に、`putImageData()` およびキャンバスの内容の一般的な操作に関するさらなる情報があります。

構文
--

```js
putImageData(imageData, dx, dy)
putImageData(imageData, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight)
```

### 引数

`imageData`

ピクセル値の配列を持った `ImageData` オブジェクトです。

`dx`

描画先キャンバスに画像データを配置する横位置 (x 座標) です。

`dy`

描画先キャンバスに画像データを配置する縦位置 (y 座標) です。

`dirtyX` 省略可

画像データを取り出し始める左上の角の横位置 (x 座標) です。デフォルト値は `0` です。

`dirtyY` 省略可

画像データを取り出し始める左上の角の縦位置 (y 座標) です。デフォルト値は `0` です。

`dirtyWidth` 省略可

描画する矩形の幅です。デフォルト値は画像データの幅です。

`dirtyHeight` 省略可

描画する矩形の高さです。デフォルト値は画像データの高さです。

### 返値

なし (`undefined`)

### 例外

`NotSupportedError` `DOMException`

引数のいずれかが無限のとき投げられます。

`InvalidStateError` `DOMException`

指定された `ImageData` オブジェクトのデータがデタッチされているとき投げられます。

例
-

### putImageData を理解する

このアルゴリズムが中で何をやっているかを理解するために、`CanvasRenderingContext2D.fillRect()` を用いた実装を用意しました。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

```js
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

function putImageData(
  ctx,
 imageData,
 dx,
 dy,
 dirtyX,
 dirtyY,
 dirtyWidth,
 dirtyHeight,
) {
  const data = imageData.data;
  const height = imageData.height;
  const width = imageData.width;
  dirtyX = dirtyX || 0;
  dirtyY = dirtyY || 0;
  dirtyWidth = dirtyWidth !== undefined ? dirtyWidth : width;
  dirtyHeight = dirtyHeight !== undefined ? dirtyHeight : height;
  const limitBottom = dirtyY + dirtyHeight;
  const limitRight = dirtyX + dirtyWidth;
  for (let y = dirtyY; y < limitBottom; y++) {
    for (let x = dirtyX; x < limitRight; x++) {
      const pos = y \* width + x;
      ctx.fillStyle = `rgba(${data[pos \* 4 + 0]}, ${data[pos \* 4 + 1]}, ${
 data[pos \* 4 + 2]
 }, ${data[pos \* 4 + 3] / 255})`;
      ctx.fillRect(x + dx, y + dy, 1, 1);
    }
  }
}

// 内容をキャンバスに描画する
ctx.fillRect(0, 0, 100, 100);
// 描画内容から ImageData オブジェクトを生成する
const imagedata = ctx.getImageData(0, 0, 100, 100);
// putImageData の動作の説明用の putImageData 関数を用いる
putImageData(ctx, imagedata, 150, 0, 50, 50, 25, 25);
```

#### 結果

### ブラウザーの最適化によるデータの消失

**警告:** 乗算済みアルファカラー値との変換ではデータが劣化するため、`putImageData()` でピクセルを設定した直後でも、対応する `getImageData()` で異なる値として読み込まれる可能性があります。

#### JavaScript

```js
const canvas = document.createElement("canvas");
canvas.width = 1;
canvas.height = 1;
const context = canvas.getContext("2d");
const imgData = context.getImageData(0, 0, canvas.width, canvas.height);
const pixels = imgData.data;
pixels[0 + 0] = 1;
pixels[0 + 1] = 127;
pixels[0 + 2] = 255;
pixels[0 + 3] = 1;
console.log("before:", pixels);
context.putImageData(imgData, 0, 0);
const imgData2 = context.getImageData(0, 0, canvas.width, canvas.height);
const pixels2 = imgData2.data;
console.log("after:", pixels2);
```

以下のような出力になるかもしれません。
```

before: Uint8ClampedArray(4) [ 1, 127, 255, 1 ]
after: Uint8ClampedArray(4) [ 255, 255, 255, 1 ]
```

仕様書
---

| Specification |
| --- |
| HTML Standard # dom-context-2d-putimagedata-dev |

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

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

関連情報
----

* このメソッドを定義しているインターフェイス: `CanvasRenderingContext2D`
* `ImageData` オブジェクト
* `CanvasRenderingContext2D.getImageData()`
* キャンバスとピクセル操作


CanvasRenderingContext2D: shadowColor プロパティ - Web API

CanvasRenderingContext2D: shadowColor プロパティ
===========================================

Canvas 2D API の **`CanvasRenderingContext2D.shadowColor`** プロパティは、影の色を設定します。

描画時の影の不透明度は、塗りつぶしでは `fillStyle` の色の、線の描画では `strokeStyle` の色の影響を受けることを覚えておいてください。

**メモ:** 影はプロパティ `shadowColor` が透明でない色に設定されているときのみ描画されます。さらに、プロパティ `shadowBlur`、`shadowOffsetX`、`shadowOffsetY` のいずれかがゼロでない値に設定されていなければなりません。

値
-

CSS の `<color>` の値として解析される文字列です。デフォルト値は完全に透明な黒です。

例
-

### 図形に影を加える

この例では、2 個の正方形に影を加えます。正方形のうち 1 個は塗りつぶされ、もう 1 個は線で描かれます。`shadowColor` プロパティで影の色を設定し、`shadowOffsetX` と `shadowOffsetY` で影の図形からの相対位置を設定します。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

```js
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

// 影
ctx.shadowColor = "red";
ctx.shadowOffsetX = 10;
ctx.shadowOffsetY = 10;

// 塗りつぶす長方形
ctx.fillRect(20, 20, 100, 100);

// 線で描く長方形
ctx.lineWidth = 6;
ctx.strokeRect(170, 20, 100, 100);
```

#### 結果

### 半透明な図形の影

影の不透明度は (`shadowColor` では完全に不透明な値を設定していても) 親オブジェクトの透明度の影響を受けます。この例では、半透明の色の長方形を線で描き、塗りつぶしを行います。

#### HTML

```html
<canvas id="canvas"></canvas>
```

#### JavaScript

塗りつぶす影のアルファ値は `.8 * .2` すなわち `.16` になります。線で描く影のアルファ値は `.8 * .6` すなわち `.48` になります。

```js
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

// 影
ctx.shadowColor = "rgba(255, 0, 0, .8)";
ctx.shadowBlur = 8;
ctx.shadowOffsetX = 30;
ctx.shadowOffsetY = 20;

// 塗りつぶす長方形
ctx.fillStyle = "rgba(0, 255, 0, .2)";
ctx.fillRect(10, 10, 150, 100);

// 線で描く長方形
ctx.lineWidth = 10;
ctx.strokeStyle = "rgba(0, 0, 255, .6)";
ctx.strokeRect(10, 10, 150, 100);
```

#### 結果

仕様書
---

| Specification |
| --- |
| HTML Standard # dom-context-2d-shadowcolor-dev |

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

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

### WebKit/Blink 固有の注意点

WebKit ベースおよび Blink ベースのブラウザーでは、このプロパティに加え、非標準で非推奨のメソッド `ctx.setShadow()` が実装されています。

```js
setShadow(width, height, blur, color, alpha);
setShadow(width, height, blur, graylevel, alpha);
setShadow(width, height, blur, r, g, b, a);
setShadow(width, height, blur, c, m, y, k, a);
```

関連情報
----

* このプロパティを定義しているインターフェイス: `CanvasRenderingContext2D`