WebGPU API - Web API 接口参考

WebGPU API
==========

**实验性:** **这是一项实验性技术**
在将其用于生产之前，请仔细检查浏览器兼容性表格。

**WebGPU API** 使 web 开发人员能够使用底层系统的 GPU（图形处理器）进行高性能计算并绘制可在浏览器中渲染的复杂图形。

WebGPU 是 WebGL 的继任者，为现代 GPU 提供更好的兼容、支持更通用的 GPU 计算、更快的操作以及能够访问到更高级的 GPU 特性。

概念和使用
-----

很公平地说，WebGL 在 2011 年左右首次出现后，在图形功能方面彻底改变了 web。WebGL 是 OpenGL ES 2.0 图形库的 JavaScript 端口，允许 web 页面直接将渲染计算传递给设备的 GPU，这会以非常高的速度处理，并在 `<canvas>` 内渲染结果。

WebGL 和用于编写 WebGL 着色器代码的 GLSL 语言十分复杂，因此创建了几个 WebGL 库，以便更轻松地编写 WebGL 应用程序：流行的示例包括 Three.js、Babylon.js 以及 PlayCanvas。开发者可以使用这些工具去构建身临其境的基于 web 3D 的游戏、音乐视频、培训和建模工具、VR 和 AR 体验等。

然而，WebGL 有一些需要解决的基本问题：

* 自 WebGL 发布以来，出现了新一代的原生 GPU API——最受欢迎的是微软的 Direct3D 12、苹果的 Metal 以及科纳斯组织的 Vulkan——它们提供了大量新特性。并没有任何计划对 OpenGL（以及 WebGL）进行更多更新，因此它将不会获得任意这些新的特性。然而，WebGPU 将在未来添加这些新特性。
* WebGL 完全基于绘制图形并将它们渲染到画布的用例。它并不能很好地处理通用 GPU（GPGPU）的计算。GPGPU 计算对于很多不同的用例显得越来越重要，例如那些基于机器学习的模型。
* 无论是在同时渲染的对象方面，还是新渲染特性的使用方面，3D 图形应用程序的需求都在逐渐变高。

WebGPU 解决了这些问题，其提供了与现代 GPU API 兼容的更新的通用架构，它会让你感到更加丝滑。它支持图形渲染，同时对 GPGPU 计算也有一流的支持。在 CPU 端渲染单个对象的成本要低得多，并且它支持现代化的 GPU 渲染特性，例如，基于计算的粒子和用于后期处理的滤镜，如颜色效果、锐化和景深模拟。此外，它也可以直接在 GPU 上处理诸如剔除和骨骼动画模型等耗费大量计算资源的任务。

通用模型
----

设备 GPU 和运行 WebGPU API 的 web 浏览器之间有多个抽象层。理解这些，对你开始学习 WebGPU 很有用：

![提供一个基本的堆栈图，展示 WebGPU 架构中不同元素在设备上的位置关系。](/zh-CN/docs/Web/API/WebGPU_API/basic-webgpu-stack.png)

* 物理设备具有 GPU。大多数设备仅有一个 GPU，但有些设备不止一个。可以使用的不同 GPU 类型：
    + 集显（Integrated GPU），与 CPU 位于同一主板上，并共享其内存。
    + 独显（Discrete GPU），位于单独的显卡上，与 CPU 分开。
    + 软件 GPU（Software "GPU"），在 CPU 上实现。
**备注：** 上图假设仅有一个 CPU 设备。
* 本机 GPU API 是操作系统（例如 macOS 上的 Metal）的一部分，是一种允许本机应用程序使用 GPU 功能的编程接口。API 指令通过驱动程序发送到 GPU（并接收响应）。一个系统可以有多个本机操作系统 API 和驱动程序可用于与 GPU 通信，尽管上述图示仅假设一个设备仅有一个本机 API/驱动器程序。
* 浏览器的 WebGPU 实现了通过本机 GPU API 与 GPU 进行通信。WebGPU 设配器在你的代码中实际上表示地是一个物理 GPU 和可利用的驱动程序。
* 逻辑设备是一种抽象，通过它，单个 web 应用程序可以以分区的方式访问 GPU 功能。逻辑设备需要提供复用的功能。因为一个物理设备的 GPU 可能同时被多个应用程序和进程使用，包括许多 web 引用程序。为了安全和逻辑上的原因，每个 web 应用程序都需要能够隔离地访问 WebGPU。
获取设备的访问权限
---------

逻辑设备（通过 `GPUDevice` 对象实例表示）是 web 应用程序访问所有 WebGPU 功能的基础。访问设备的过程如下：

1. `Navigator.gpu` 属性（或 `WorkerNavigator.gpu`，如果你在 worker 内部使用 WebGPU 功能）为当前上下文返回 `GPU` 对象。
2. 通过 `GPU.requestAdapter()` 方法访问适配器。该方法接受一个可选的设置对象，其允许你请求一个高性能或者低功耗的适配器。如果没有可选的对象，设备将提供对默认适配器的访问，这对于大多数用途来说足够了。
3. 设备可以通过 `GPUAdapter.requestDevice()` (en-US) 请求。该方法接受一个可选的对象（称为描述符），该设备可以用于指定你想要逻辑设备具有的确切特性和限制。如果没有可选的对象，所提供的设备将使用合理的通用的规则，这对于大多数用途来说够了。

将其与一些特性检测检查结合起来，可以按如下方式实现上述过程：

```js
async function init() {
  if (!navigator.gpu) {
    throw Error("WebGPU not supported.");
  }

  const adapter = await navigator.gpu.requestAdapter();
  if (!adapter) {
    throw Error("Couldn't request WebGPU adapter.");
  }

  const device = await adapter.requestDevice();

  //...
}
```

管线和着色器：WebGPU 应用程序的构成
---------------------

管线（pipeline）是一个逻辑结构，其包含在你完成程序工作的可编程阶段。WebGPU 目前能够处理两种类型的管线：

* 渲染管线用于渲染图形，通常渲染到 `<canvas>` 元素中，但它也可以在画面之外的地方渲染图形。它有两个主要阶段：
    + 顶点着色阶段：在该阶段中，顶点着色器（vertex shader）接受 GPU 输入的位置数据并使用像旋转、平移或透视等特定的效果将顶点在 3D 空间中定位。然后，这些顶点会被组装成基本的渲染图元，例如三角形等，然后通过 GPU 进行光栅化，计算出每个顶点应该覆盖在 canvas 上的哪些像素。
    + 片元着色阶段：在该阶段中，片元着色器（fragment shader）计算由顶点着色器生成的基本图元所覆盖的每个像素的颜色。这些计算通常使用输入，如图像（以纹理的方式）提供表面细节以及虚拟化光源的位置和颜色。
* 计算管线用于通用计算。计算管线包含单独的计算阶段，在该阶段中，计算着色器（compute shader）接受通用的数据，在指定数量的工作组之间并行处理数据，然后将结果返回到一个或者多个缓冲区。这些缓冲区可以包含任意类型的数据。

上面提到的着色器是通过 GPU 处理的指令集。WebGPU 着色器语言是用称为 WebGPU 着色器语言（WGSL）的低级的类 Rust 语言编写的。

你可以通过几种不同的方式去构建 WebGPU 应用程序，但该过程应包含以下步骤：

1. 创建着色器模块：在 WGSL 写你的着色器代码并将其打包到一个或者多个着色器模块。
2. 获取和配置 canvas 上下文：获取 `<canvas>` 元素的 `webgpu` 上下文并将其配置为从你的 GPU 逻辑设备接收有关渲染的图形信息。如果你的应用程序没有图形输出（例如仅使用计算管线），则此步骤是不需要的。
3. 创建包含你数据的资源：你想要通过你的管线处理的数据存储在 GPU 缓冲区或者纹理中，以供应用程序访问。
4. 创建管线：定义管线描述符，详细地描述管线，包含所需的数据结构、绑定、着色器和资源布局，然后从中创建管线。我们的基本演示仅包含单个管线，但复杂的应用程序通常会包含多个用于不同目的的管线。
5. 允许计算/渲染通道：这涉及许多子步骤：
    1. 创建一个指令编码器，它可以对一组传递给 GPU 的指令执行编码。
    2. 创建一个通道编码器对象，该对象用于发出计算/渲染指令。
    3. 运行指令，指定使用哪些管线、从哪个缓冲区获取数据、运行多少次绘制操作等。
    4. 完成指令列表后，将其封装到指令缓冲区中。
    5. 通过逻辑设备的指令队列提交指令到缓冲区。

在下面的部分，我们将研究一个基本的渲染管线演示，让你知道探索它需要什么。稍后，我们也将研究一个基础的计算管线示例，看看它与渲染管线有什么不同。

基础的渲染管线
-------

在我们的基础的渲染管线示例中，我们给 `<canvas>` 元素一个纯蓝色背景并且在其上绘制三角形。

### 创建着色器模块

我们使用以下着色器代码。顶点着色阶段（`@vertex` 代码块）接受包含位置和颜色的数据分块，根据给定的位置定位顶点，插入颜色，然后将数据传入到片元着色器阶段。片元着色阶段（`@fragment` 代码块）接受来自顶点着色器阶段的数据，并根据给定的颜色为顶点着色。

```js
const shaders = `
struct VertexOut {
 @builtin(position) position : vec4f,
 @location(0) color : vec4f
}

@vertex
fn vertex\_main(@location(0) position: vec4f,
 @location(1) color: vec4f) -> VertexOut
{
 var output : VertexOut;
 output.position = position;
 output.color = color;
 return output;
}

@fragment
fn fragment\_main(fragData: VertexOut) -> @location(0) vec4f
{
 return fragData.color;
}
`;
```

**备注：** 在我们的演示中，我们将我们的代码存储在模板字面量中，但是你可以将其存储在任何地方，以便可以很容易地将其作为文本取回，并输入到你的 WebGPU 程序中。例如，另一种常见的作法是将着色器存储在 `<script>` 元素中并且使用 `Node.textContent` 取回内容。用于 WGSL 的正确 MIME 类型是 `text/wgsl`。

为了确保你的着色器代码可提供给 WebGPU，你必须通过 `GPUDevice.createShaderModule()` (en-US) 调用，将其放入 `GPUShaderModule` (en-US) 中，将你的着色器代码作为描述符对象中的属性传递。例如：

```js
const shaderModule = device.createShaderModule({
  code: shaders,
});
```

### 获取和配置 canvas 上下文

在渲染管线中，我们需要指定在哪个位置渲染图形。在这种情况下，我们获得对屏幕上 `<canvas>` 元素的引用，然后使用 `webgpu` 参数调用 `HTMLCanvasElement.getContext()`，以返回它的 GPU 上下文（一个 `GPUCanvasContext` 实例）。

从这里继续，我们将通过调用 `GPUCanvasContext.configure()` 去配置上下文，向它传递包含渲染信息的可选对象，包括 `GPUDevice`、纹理的格式以及在半透明纹理时使用的 alpha 模式。

```js
const canvas = document.querySelector("#gpuCanvas");
const context = canvas.getContext("webgpu");

context.configure({
  device: device,
  format: navigator.gpu.getPreferredCanvasFormat(),
  alphaMode: "premultiplied",
});
```

**备注：** 确定纹理格式的最佳做法是使用 `GPU.getPreferredCanvasFormat()` 方法；这将为用户的设备选择最有效的格式（`bgra8unorm` 或 `rgba8unorm`）。

### 创建缓冲区并将我们的三角形数据写入

接下来，我们将以 WebGPU 可以使用的数据形式向它的程序提供我们的数据。我们的数据最初在 `Float32Array` 中提供，每个三角形包含 8 个数据点——X、Y、Z、W 代表位置，R、G、B、A 代表颜色。

```js
const vertices = new Float32Array([
  0.0, 0.6, 0, 1, 1, 0, 0, 1, -0.5, -0.6, 0, 1, 0, 1, 0, 1, 0.5, -0.6, 0, 1, 0,
  0, 1, 1,
]);
```

但是，我们这里有一个问题。我们需要将我们的数据放入 `GPUBuffer` (en-US)。在幕后，这种类型的缓冲区与 GPU 的核心非常紧密的集成在一起，以实现所需的高性能处理。由于副作用，该内存不能通过主机系统上运行的进程（例如浏览器）访问。

`GPUBuffer` (en-US) 通过调用 `GPUDevice.createBuffer()` (en-US) 创建。我们给它与 `vertices` 数组长度等同的大小，这样它可以包含所有数据，以及 `VERTEX` 和 `COPY_DST` 使用标志去指示缓冲区将用于顶点缓冲区和复制操作的目的地。

```js
const vertexBuffer = device.createBuffer({
  size: vertices.byteLength, // make it big enough to store vertices in
  usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY\_DST,
});
```

我们将使用映射操作将我们的数据放入 `GPUBuffer`，就像我们在计算管线实例中，将数据从 GPU 读回到 JavaScript。然而，在这种情况下，我们将使用便利的 `GPUQueue.writeBuffer()` (en-US) 方法，它将要写入缓冲区的、要写入数据源的、每个偏移值和要写入数据的的大小作为参数（我们已经指定了数据的整个长度）。然后浏览器会找出写入数据的最高效的方式。

```js
device.queue.writeBuffer(vertexBuffer, 0, vertices, 0, vertices.length);
```

### 定义和创建渲染管线

现在我们已经将数据放入缓冲区，设置的下一部分是实际创建我们的管线，为渲染准备好。

首先，我们创建一个对象，该对象描述我们顶点数据所需的布局。这完美地描述了我们在 `vertices` 数组和顶点着色阶段看到的内容——每个顶点都有位置和颜色数据。两者都采用 `float32x4` 格式（映射到 WGSL 的 `vec4<f32>` 类型），颜色数据从每个顶点的 16 字节偏移量开始。`arrayStride` 指定了步幅，表示构成每个顶点的字节数，`stepMode` 指定了应该按顶点获取数据。

```js
const vertexBuffers = [
  {
    attributes: [
      {
        shaderLocation: 0, // 位置
        offset: 0,
        format: "float32x4",
      },
      {
        shaderLocation: 1, // 颜色
        offset: 16,
        format: "float32x4",
      },
    ],
    arrayStride: 32,
    stepMode: "vertex",
  },
];
```

下一步，我们创建一个描述符对象，该对象指定了我们渲染管线阶段的配置。对于两个着色阶段，我们指定了可以在 `shaderModule` 中找到相关代码的 `GPUShaderModule` (en-US)，以及找到每个阶段入口点的函数名称。

此外，在顶点着色阶段，我们提供我们的 `vertexBuffers` 对象，来提供顶点数据的预期状态。在我们的片元着色阶段，我们提供了一组颜色目标说明的数组，其指示渲染的格式（这与我们之前在 canvas 上下文配置中指定的格式相匹配）。

我们也指定了一个 `primitive` 说明，在这种情况下，它只是说明了我们将要绘制的原始类型，以及 `layout` 为 `auto`。`layout` 属性定义了在管线执行期间，所有 GPU 资源（缓冲区、纹理等）的布局（结构、用途和类型。在更复杂的应用程序中，这将采用 `GPUPipelineLayout` (en-US) 对象的形式，使用 `GPUDevice.createPipelineLayout()` (en-US) 创建（你可以在我们的基础的计算管线看见这个示例），它允许 GPU 提前弄清楚如何更有效地运行管线。然而，在这里我们指定了 `auto` 值，这将导致管线基于着色器代码中定义的任何绑定生成隐式绑定组布局。

```js
const pipelineDescriptor = {
  vertex: {
    module: shaderModule,
    entryPoint: "vertex\_main",
    buffers: vertexBuffers,
  },
  fragment: {
    module: shaderModule,
    entryPoint: "fragment\_main",
    targets: [
      {
        format: navigator.gpu.getPreferredCanvasFormat(),
      },
    ],
  },
  primitive: {
    topology: "triangle-list",
  },
  layout: "auto",
};
```

最终，我们通过传递 `pipelineDescriptor` 参数给 `GPUDevice.createRenderPipeline()` (en-US) 方法调用，我们创建了一个 `GPURenderPipeline` (en-US)。

```js
const renderPipeline = device.createRenderPipeline(pipelineDescriptor);
```

### 运行渲染通道

现在所有设置都已完成，实际上，我们可以运行一个渲染通道并在我们的 `<canvas>` 上进行绘制。为了对稍后发送给 GPU 的任何指令进行编码，你需要创建一个 `GPUCommandEncoder` (en-US) 实例，这是调用 `GPUDevice.createCommandEncoder()` (en-US) 完成的。

```js
const commandEncoder = device.createCommandEncoder();
```

下一步，我们通过调用 `GPUCommandEncoder.beginRenderPass()` (en-US) 创建 `GPURenderPassEncoder` (en-US) 实例来开始运行渲染通道。该方法采用一个描述符对象作为参数，唯一的必须属性是 `colorAttachments` 数组。在该实例中，我们指定了：

1. 要渲染到的纹理视图；我们通过 `context.getCurrentTexture().createView()` (en-US) 从 `<canvas>` 创建一个新视图。
2. 纹理视图一旦加载并且在任何绘制发生之前，将“清除”视图到一个指定的颜色。这就是导致三角形后面出现蓝色背景的原因。
3. 我们还要在当前的渲染通道中存储这个颜色附件的值。

```js
const clearColor = { r: 0.0, g: 0.5, b: 1.0, a: 1.0 };

const renderPassDescriptor = {
  colorAttachments: [
    {
      clearValue: clearColor,
      loadOp: "clear",
      storeOp: "store",
      view: context.getCurrentTexture().createView(),
    },
  ],
};

const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
```

现在，我们可以调用渲染通道编码器的方法去绘制我们的三角形：

1. 将我们的 `renderPipeline` 对象作为 `GPURenderPassEncoder.setPipeline()` (en-US) 方法的参数调用，以指定用于渲染管线的通道。
2. 将我们的 `vertexBuffer` 对象作为 `GPURenderPassEncoder.setVertexBuffer()` (en-US) 方法的参数调用，作为数据源传递给管线进行渲染。第一个参数是设置顶点缓冲区的插槽，这是对 `vertexBuffers` 数组中描述该缓冲区布局的元素索引的引。
3. `GPURenderPassEncoder.draw()` (en-US) 设置动态绘制。在我们的 `vertexBuffer` 中有三个顶点的数据，所以我们将顶点数值设置为 `3` 去绘制它们。

```js
passEncoder.setPipeline(renderPipeline);
passEncoder.setVertexBuffer(0, vertexBuffer);
passEncoder.draw(3);
```

要完成对指令序列的编码并将它们发送给 GPU，还需要三个步骤。

1. 我们调用 `GPURenderPassEncoder.end()` (en-US) 方法去给渲染指令列表发出结束的信号。
2. 我们调用 `GPUCommandEncoder.finish()` (en-US) 方法去完成对发出指令序列的记录，并将其封装到 `GPUCommandBuffer` (en-US) 对象中。
3. 我们提交 `GPUCommandBuffer` (en-US) 到设备的指令队列中（通过 `GPUQueue` (en-US) 实例表示）已发送给 GPU。这个设备的队列可以通过 `GPUDevice.queue` (en-US) 属性获取，并可以通过 `GPUQueue.submit()` (en-US) 调用将 `GPUCommandBuffer` (en-US) 实例数组增加到队列中。

这三个步骤可以通过以下两行来实现。

```js
passEncoder.end();

device.queue.submit([commandEncoder.finish()]);
```

基础的计算管线
-------

在我们的基础计算演示中，我们让 GPU 计算一些值，将它们存储到输出缓存中，将数据复制到暂存缓冲区，然后映射该暂存缓冲区，以便数据可以读出到 JavaScript 并且记录到控制台。

该应用程序与基础的渲染演示有着相似的结构。我们以与之前相同的方式创建一个 `GPUDevice` 引用，并通过调用 `GPUDevice.createShaderModule()` (en-US) 将我们的着色器代码封装到 `GPUShaderModule` (en-US)。这里的区别在于我们的着色器代码仅有一个着色阶段，`@compute` 阶段：

```js
// 定义全局的缓冲区大小
const BUFFER\_SIZE = 1000;

const shader = `
@group(0) @binding(0)
var<storage, read\_write> output: array<f32>;

@compute @workgroup\_size(64)
fn main(
 @builtin(global\_invocation\_id)
 global\_id : vec3u,

 @builtin(local\_invocation\_id)
 local\_id : vec3u,
) {
 // Avoid accessing the buffer out of bounds
 if (global\_id.x >= ${BUFFER\_SIZE}) {
 return;
 }

 output[global\_id.x] =
 f32(global\_id.x) \* 1000. + f32(local\_id.x);
}
`;
```

### 创建缓冲区处理我们的数据

在该示例中，我们创建了两个 `GPUBuffer` (en-US) 实例去处理我们的数据，`output` 缓冲区高速地写入 GPU 计算结果，`stagingBuffer` 缓冲区用于将 `output` 的内容复制到自身，它可以被映射以允许 JavaScript 访问这些值。

* 指定 `output` 为一个存储缓冲区，它将成为复制操作的源。
* 指定 `stagingBuffer` 可以被映射为一个由 JavaScript 读取的缓冲区，并将成为复制操作的目标。

```js
const output = device.createBuffer({
  size: BUFFER\_SIZE,
  usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY\_SRC,
});

const stagingBuffer = device.createBuffer({
  size: BUFFER\_SIZE,
  usage: GPUBufferUsage.MAP\_READ | GPUBufferUsage.COPY\_DST,
});
```

### 创建绑定组布局

当创建管线时，我们需要为管线指定一个绑定组。这将首先创建 `GPUBindGroupLayout` (en-US)（通过调用 `GPUDevice.createBindGroupLayout()` (en-US)），该布局定义了 GPU 资源（例如将在此管线中使用的缓冲区）的结构和用途。此布局将用作绑定组的模板。在这种情况下，我们将管线与一个单一的内存缓冲区绑定，绑定到绑定槽 0（这与我们的着色器代码中的相关绑定号匹配——`@binding(0)`），可在管线的计算阶段使用，并将缓冲区的用途定义为 `storage`。

```js
const bindGroupLayout = device.createBindGroupLayout({
  entries: [
    {
      binding: 0,
      visibility: GPUShaderStage.COMPUTE,
      buffer: {
        type: "storage",
      },
    },
  ],
});
```

下一步，我们通过调用 `GPUDevice.createBindGroup()` (en-US) 创建 `GPUBindGroup` (en-US)。我们通过此方法调用一个描述符对象，该对象指定了这个绑定组应该基于的绑定组布局，以及绑定到布局中定义的插槽变量的详细信息。在这种情况下，我们声明了绑定插槽 0，并指定了之前定义的 `output` 缓冲区应该绑定到它。

```js
const bindGroup = device.createBindGroup({
  layout: bindGroupLayout,
  entries: [
    {
      binding: 0,
      resource: {
        buffer: output,
      },
    },
  ],
});
```

**备注：** 你可以通过调用 `GPUComputePipeline.getBindGroupLayout()` (en-US) 方法检索在创建绑定组时使用的隐式布局。还有一个可以用于渲染管线的版本：参见 `GPURenderPipeline.getBindGroupLayout()` (en-US)。

### 创建计算管线

上述一切就绪后，我们现在可以通过调用 `GPUDevice.createComputePipeline()` (en-US) 并向它传递一个管线描述符对象创建计算管线。这与创建渲染管线的方式类似。我们描述计算着色器，指定在哪个模块中查找代码以及入口点是什么。我们也为管线指定了 `layout`，在本例中，我们通过调用 `GPUDevice.createPipelineLayout()` (en-US) 创建一个基于之前定义的 `bindGroupLayout` 的布局。

```js
const computePipeline = device.createComputePipeline({
  layout: device.createPipelineLayout({
    bindGroupLayouts: [bindGroupLayout],
  }),
  compute: {
    module: shaderModule,
    entryPoint: "main",
  },
});
```

唯一的区别是，这里我们没有指定原始类型，因为我们不需要绘制任何东西。

### 运行计算通道

在结构上，运行计算通道与运行渲染通道类似。首先，我们使用 `GPUCommandEncoder.beginComputePass()` (en-US) 创建通道编码器。

在发出指令时，我们使用相同的方式指定管线，使用 `GPUComputePassEncoder.setPipeline()` (en-US)。然后，我们使用 `GPUComputePassEncoder.setBindGroup()` (en-US) 指定想要使用的 `bindGroup` 来指定在计算中使用的数据，并使用 `GPUComputePassEncoder.dispatchWorkgroups()` (en-US) 指定要运行并行计算的 GPU 工作组的数量。

最后，我们使用 `GPURenderPassEncoder.end()` (en-US) 发出渲染通道指令结束的信号。

```js
passEncoder.setPipeline(computePipeline);
passEncoder.setBindGroup(0, bindGroup);
passEncoder.dispatchWorkgroups(Math.ceil(BUFFER\_SIZE / 64));

passEncoder.end();
```

### 将结果读回 JavaScript

在使用 `GPUQueue.submit()` (en-US) 将编码指令提交给 GPU 执行之前，我们使用 `GPUCommandEncoder.copyBufferToBuffer()` (en-US) 将 `output` 缓冲区的内容复制到 `stagingBuffer` 缓冲区中。

```js
// 复制 output 缓冲去到 staging 缓冲区
commandEncoder.copyBufferToBuffer(
  output,
  0, // 来源缓冲区偏移量
  stagingBuffer,
  0, // 目的缓冲区偏移量
  BUFFER\_SIZE,
);

// 通过将命令缓冲区数组传递给命令队列以执行来结束
device.queue.submit([commandEncoder.finish()]);
```

一旦输出数据可用于 `stagingBuffer`，我们使用 `GPUBuffer.mapAsync()` (en-US) 方法将数据映射到中间内存，并使用 `GPUBuffer.getMappedRange()` (en-US) 获取映射范围的引用，将数据复制到 JavaScrip，并将其记录到控制台。完成后，我们还会取消映射到 `stagingBuffer`。

```js
// 映射 staging 缓冲区，以便读回到 JS
await stagingBuffer.mapAsync(
  GPUMapMode.READ,
  0, // 偏移量
  BUFFER\_SIZE, // 长度
);

const copyArrayBuffer = stagingBuffer.getMappedRange(0, BUFFER\_SIZE);
const data = copyArrayBuffer.slice();
stagingBuffer.unmap();
console.log(new Float32Array(data));
```

GPU 错误处理
--------

WebGPU 调用在 GPU 进程中以异步的方式进行验证。如果发现错误，有问题的调用会在 GPU 端标记为无效。如果依赖于一个无效调用返回值的另一个调用被执行，那么该对象将也被标记为无效，以此类推。因此，WebGPU 的错误被称为“传染性错误”。

每个 `GPUDevice` 实例都维护这自己的错误作用域栈。这个栈最初是空的，但是你可以通过调用 `GPUDevice.pushErrorScope()` (en-US) 来开始推入错误作用域到栈，以捕获特定类型的错误。

一旦完成错误捕获，你可以通过调用 `GPUDevice.popErrorScope()` (en-US) 来结束捕获。这会从栈中弹出作用域并返回一个 `Promise`，该 Promise 兑现为一个对象（`GPUInternalError` (en-US)、`GPUOutOfMemoryError` (en-US) 或 `GPUValidationError` (en-US)），描述在作用域内捕获的第一个错误，如果没有错误捕获，则是 `null`。

在适当的“验证”部分，我们试图去提供帮助你理解为什么你的 WebGPU 代码发生错误的有用信息，其中列出了避免错误的条件。例如，参见 `GPUDevice.createBindGroup()` 检验部分 (en-US)。其中一些信息很复杂，我们决定仅列出以下错误标准，而不是重复规范：

* 不明显的错误标准，例如导致验证错误的描述符属性的组合。没有必要告诉你确保使用正确的描述符对象结构。这既是显而易见的又是模糊的。
* 由开发者控制的错误标准。一些错误标准仅基于内部因素，对于 web 开发者并不真正相关。

你可以在关于 WebGPU 错误处理的解释中找到更多有关信息——参见对象的有效性和销毁状态以及错误。WebGPU 错误处理的最佳实践提供了很多有关真实世界的示例和建议的有用信息。

**备注：** 在 WebGL 中处理错误的历史方式是提供一个 `getError()` (en-US) 方法，该方法返回错误的信息。这种方式存在问题，因为它会同步返回错误，这对性能是不利的——每次调用都需要往返到 GPU 并且需要所有先前发出的操作都已经完成。它的状态模型也是扁平的，这意味着错误可以在不相关的代码之间泄露。WebGPU 的创建者决定改变这一点。

接口
--

### API 的入口点

`Navigator.gpu` / `WorkerNavigator.gpu`

API 的入口点——返回当前上下文的 `GPU` 对象。

`GPU`

使用 WebGPU 的起点。它可用于返回 `GPUAdapter`。

`GPUAdapter`

表示 GPU 适配器。你可以从这里请求 `GPUDevice`、适配器信息、特性和限制。

`GPUAdapterInfo`

包含有关适配器的标识信息。

### 配置 GPUDevice

`GPUDevice`

表示逻辑 GPU 设备。这是访问大多数 WebGPU 功能的主要接口。

`GPUSupportedFeatures` (en-US)

一个类 Set 对象，该对象通过 `GPUAdapter` 或 `GPUDevice` 描述了额外的功能。

`GPUSupportedLimits` (en-US)

描述 `GPUAdapter` 或 `GPUDevice` 支持的限制。

### 配置渲染 `<canvas>`

`HTMLCanvasElement.getContext()`——`contextType` 为 `"webgpu"`

使用 `contextType` 为 `"webgpu"` 调用 `getContext()` 方法，其会返回一个 `GPUCanvasContext` 对象实例，然后可以使用 `GPUCanvasContext.configure()` 对其进行配置。

`GPUCanvasContext`

表示 `<canvas>` 元素的 WebGPU 渲染上下文。

### 表示管线资源

`GPUBuffer` (en-US)

表示内存块，其可以用于在 GPU 操作中存储原始数据。

`GPUExternalTexture` (en-US)

包含 `HTMLVideoElement` 快照的包装器对象，可用作 GPU 渲染操作中的纹理。

`GPUSampler` (en-US)

控制着色器如何转换和过滤纹理资源数据。

`GPUShaderModule` (en-US)

对内部着色器模块对象的引用，它是 WGSL 着色器代码的容器，通过管线提交给 GPU 执行。

`GPUTexture` (en-US)

用于存储 1D、2D 或 3D 数据数组（例如图像）以在 GPU 渲染操作中使用的容器。

`GPUTextureView` (en-US)

由特定 `GPUTexture` (en-US) 定义的纹理子资源的某个子集的视图。

### 表示管线

`GPUBindGroup` (en-US)

基于 `GPUBindGroupLayout` (en-US)，`GPUBindGroup` 定义了一组要绑定在一起的资源以及如何在着色阶段使用这些资源。

`GPUBindGroupLayout` (en-US)

定义相关 GPU 资源的结构和用途，例如将在管线中使用的缓冲区，并在创建 `GPUBindGroup` (en-US) 时用作模板。

`GPUComputePipeline` (en-US)

控制计算着色阶段，可以在 `GPUComputePassEncoder` (en-US) 中使用。

`GPUPipelineLayout` (en-US)

定义管线使用的 `GPUBindGroupLayout` (en-US)。在指令编码期间与管线一起使用的 `GPUBindGroup` (en-US) 必须具有兼容的 `GPUBindGroupLayout` (en-US)。

`GPURenderPipeline` (en-US)

控制顶点和片元着色阶段，可以在 `GPURenderPassEncoder` (en-US) 或 `GPURenderBundleEncoder` (en-US) 使用。

### 编码并向 GPU 提交指令

`GPUCommandBuffer` (en-US)

表示 GPU 指令的录制列表，其可以提交给 `GPUQueue` (en-US) 执行。

`GPUCommandEncoder` (en-US)

表示指令编码器，用于编码指令发布给 GPU。

`GPUComputePassEncoder` (en-US)

编码与控制计算着色阶段相关的指令，由 `GPUComputePipeline` (en-US) 发出。是 `GPUCommandEncoder` (en-US) 整体编码激活过后的一部分。

`GPUQueue` (en-US)

控制 GPU 编码指令的执行。

`GPURenderBundle` (en-US)

预先录制的指令 bundle 的容器（参见 `GPURenderBundleEncoder` (en-US)）。

`GPURenderBundleEncoder` (en-US)

用于预先记录指令的 bundle。这些可以通过 `executeBundles()` (en-US) 方法在 `GPURenderPassEncoder` (en-US) 中根据需要重复使用。

`GPURenderPassEncoder` (en-US)

编码与控制顶点和片段着色阶段相关的指令，由 `GPURenderPipeline` (en-US) 发出。是 `GPUCommandEncoder` (en-US) 整体编码激活过后的一部分。

### 在渲染通道中执行查询

`GPUQuerySet` (en-US)

用于记录通道中查询的结果，例如遮挡或时间戳查询。

### 调试错误

`GPUCompilationInfo` (en-US)

`GPUCompilationMessage` (en-US) 对象数组，由 GPU 着色器模块编译器生成，用于帮助诊断着色器代码问题。

`GPUCompilationMessage` (en-US)

表示由 GPU 着色器模块编译器生成的单个信息、警告或错误消息。

`GPUDeviceLostInfo` (en-US)

当 `GPUDevice.lost` (en-US) `Promise` 兑现时返回，提供有关设备丢失原因的信息。

`GPUError` (en-US)

`GPUDevice.popErrorScope` (en-US) 和 `uncapturederror` (en-US) 事件显示错误的基本接口。

`GPUInternalError` (en-US)

`GPUDevice.popErrorScope` (en-US) 和 `GPUDevice` `uncapturederror` (en-US) 事件显示的错误类型之一。表示操作因系统或特定于实现的原因而失败，即使满足所有验证要求也会失败。

`GPUOutOfMemoryError` (en-US)

`GPUDevice.popErrorScope` (en-US) 和 `GPUDevice` `uncapturederror` (en-US) 事件显示的错误类型之一。表示没有足够的可用内存来完成请求的操作。

`GPUPipelineError` (en-US)

描述管线的失败。当 `GPUDevice.createComputePipelineAsync()` (en-US) 或 `GPUDevice.createRenderPipelineAsync()` (en-US) 调用返回的 `Promise` 被拒绝时，接收到的值。

`GPUUncapturedErrorEvent` (en-US)

`GPUDevice` `uncapturederror` (en-US) 事件的事件对象类型。

`GPUValidationError` (en-US)

`GPUDevice.popErrorScope` (en-US) 和 `GPUDevice` `uncapturederror` (en-US) 事件显示的错误类型之一。描述一个应用程序错误，指示操作未通过 WebGPU API 的验证约束。

示例
--

* 基础的计算示例
* 基础的渲染示例
* WebGPU 示例
规范
--

| Specification |
| --- |
| WebGPU # gpu-interface |

浏览器兼容性
------

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

参见
--

* WebGPU 最佳实践
* WebGPU 讲解
* WebGPU——全部核心，没有 canvas


File - Web API 接口参考

File
====

文件（**`File`**）接口提供有关文件的信息，并允许网页中的 JavaScript 访问其内容。

通常情况下， `File` 对象是来自用户在一个 `<input>` 元素上选择文件后返回的 `FileList` 对象，也可以是来自由拖放操作生成的 `DataTransfer` 对象，或者来自 `HTMLCanvasElement` 上的 `mozGetAsFile`() API。在 Gecko 中，特权代码可以创建代表任何本地文件的 File 对象，而无需用户交互（有关详细信息，请参阅注意事项。

`File` 对象是特殊类型的 `Blob`，且可以用在任意的 Blob 类型的 context 中。比如说， `FileReader`, `URL.createObjectURL()`, `createImageBitmap()` (en-US), 及 `XMLHttpRequest.send()` 都能处理 `Blob` 和 `File`。

参考 从 Web 应用程序使用文件 了解更多信息和例子。

构造函数
----

`File()`

返回一个新构建的文件对象（`File`）。

属性
--

`File` 接口也继承了 `Blob` 接口的属性：

`File.lastModified` 只读

返回当前 `File` 对象所引用文件最后修改时间，自 UNIX 时间起始值（1970 年 1 月 1 日 00:00:00 UTC）以来的毫秒数。

`File.lastModifiedDate` 只读
已弃用

返回当前 `File` 对象所引用文件最后修改时间的 `Date` 对象。

`File.name` 只读

返回当前 `File` 对象所引用文件的名字。

`File.size` 只读

返回文件的大小。

`File.webkitRelativePath` 只读
非标准

返回 `File` 相关的 path 或 URL。

`Blob.type` 只读

返回文件的 多用途互联网邮件扩展类型（MIME Type）

方法
--

*`File` 接口没有定义任何方法，但是它从 `Blob` 接口继承了以下方法：*

`Blob.slice([start[, end[, contentType]]])`

返回一个新的 `Blob` 对象，它包含有源 `Blob` 对象中指定范围内的数据。

规范
--

| Specification |
| --- |
| File API # file-section |

浏览器兼容性
------

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

### 注意事项

* 在 Gecko 中，你可以从 Chrome 代码中使用这个 API。详细内容参见 Using the DOM File API in chrome code。若要从 chrome 代码，JSM 和引导范围中使用它，你必须使用 `Cu.importGlobalProperties(['File']);` 来导入它。
* 从 Gecko 6.0 开始，在特权代码（比如扩展中的代码）中，可以将一个 `nsIFile` 对象传入 `File` 构造函数，从而生成一个 File 对象。
* 从 Gecko 8.0 开始，在 XPCOM 组件代码中，你可以直接使用 `new File` 来创建一个 `File` 对象，而不需要像以前那样必须实例化一个 `nsIDOMFile` 对象。`File` 对象和 `Blob` 相反，使用第二个参数作为文件名。文件名可以是任意的字符串。
```

new File( Array parts, String filename, BlobPropertyBag properties);
```

* 下列非标准属性及方法在 Gecko 7 中就被移除了：`File.fileName`、`File.fileSize`、`File.getAsBinary()`、`File.getAsDataURL()`、`File.getAsText(string encoding)` (Firefox bug 661876)。应当使用 `File.name`、`Blob.size`，和 `FileReader` 的方法来代替。
参见
--

* 如何在 Web 应用程序中使用文件
* `FileReader`
* 在 chrome 代码中使用 DOM File API 读取文件（适用于被授权在 Gecko 中运行的代码，例如 Firefox 拓展的代码）


XMLHttpRequest - Web API 接口参考

XMLHttpRequest
==============

`XMLHttpRequest`（XHR）对象用于与服务器交互。通过 XMLHttpRequest 可以在不刷新页面的情况下请求特定 URL，获取数据。这允许网页在不影响用户操作的情况下，更新页面的局部内容。`XMLHttpRequest` 在 AJAX 编程中被大量使用。

尽管名称如此，`XMLHttpRequest` 可以用于获取任何类型的数据，而不仅仅是 XML。它甚至支持 HTTP 以外的协议（包括 file:// 和 FTP），尽管可能受到更多出于安全等原因的限制。

如果你的通信流程需要从服务器端接收事件或消息数据，请考虑通过 `EventSource` 接口使用服务器发送事件。对于全双工的通信，WebSocket 可能是更好的选择。

构造函数
----

`XMLHttpRequest()`

该构造函数用于初始化一个 `XMLHttpRequest` 实例对象。在调用下列任何其他方法之前，必须先调用该构造函数，或通过其他方式，得到一个实例对象。

属性
--

*此接口继承了 `XMLHttpRequestEventTarget` 和 `EventTarget` 的属性。*

`XMLHttpRequest.onreadystatechange`

当 `readyState` 属性发生变化时，调用的事件处理器。

`XMLHttpRequest.readyState` 只读

返回 一个无符号短整型（`unsigned short`）数字，代表请求的状态码。

`XMLHttpRequest.response` 只读

返回一个 `ArrayBuffer`、`Blob`、`Document`，或 `DOMString`，具体是哪种类型取决于 `XMLHttpRequest.responseType` 的值。其中包含整个响应实体（response entity body）。

`XMLHttpRequest.responseText` 只读

返回一个 `DOMString`，该 `DOMString` 包含对请求的响应，如果请求未成功或尚未发送，则返回 `null`。

`XMLHttpRequest.responseType`

一个用于定义响应类型的枚举值（enumerated value）。

`XMLHttpRequest.responseURL` 只读

返回经过序列化（serialized）的响应 URL，如果该 URL 为空，则返回空字符串。

`XMLHttpRequest.responseXML` 只读

返回一个 `Document`，其中包含该请求的响应，如果请求未成功、尚未发送或是不能被解析为 XML 或 HTML，则返回 `null`。

`XMLHttpRequest.status` 只读

返回一个无符号短整型（`unsigned short`）数字，代表请求的响应状态。

`XMLHttpRequest.statusText` 只读

返回一个 `DOMString`，其中包含 HTTP 服务器返回的响应状态。与 `XMLHTTPRequest.status` 不同的是，它包含完整的响应状态文本（例如，"`200 OK`"）。

**备注：** 根据 HTTP/2 规范（8.1.2.4 Response Pseudo-Header Fields，响应伪标头字段），HTTP/2 没有定义任何用于携带 HTTP/1.1 状态行中包含的版本（version）或者原因短语（reason phrase）的方法。

`XMLHttpRequest.timeout`

一个无符号长整型（`unsigned long`）数字，表示该请求的最大请求时间（毫秒），若超出该时间，请求会自动终止。

`XMLHttpRequest.upload` 只读

`XMLHttpRequestUpload` (en-US)，代表上传进度。

`XMLHttpRequest.withCredentials`

一个`布尔值` (en-US)，用来指定跨域 `Access-Control` 请求是否应当带有授权信息，如 cookie 或授权 header 头。

### 非标准属性

`XMLHttpRequest.channel`只读

一个 `nsIChannel`，对象在执行请求时使用的通道。

`XMLHttpRequest.mozAnon`只读

一个布尔值，如果为真，请求将在没有 cookie 和身份验证 header 头的情况下发送。

`XMLHttpRequest.mozSystem`只读

一个布尔值，如果为真，则在请求时不会强制执行同源策略。

`XMLHttpRequest.mozBackgroundRequest`

一个布尔值，它指示对象是否是后台服务器端的请求。

### 事件处理器

作为 `XMLHttpRequest` 实例的属性之一，所有浏览器都支持 `onreadystatechange`。

后来，许多浏览器实现了一些额外的事件（`onload`、`onerror`、`onprogress` 等）。详见使用 XMLHttpRequest。

更多现代浏览器，包括 Firefox，除了可以设置 `on*` 属性外，也提供标准的监听器 `addEventListener()` API 来监听`XMLHttpRequest` 事件。

实例方法
----

`XMLHttpRequest.abort()`

如果请求已被发出，则立刻中止请求。

`XMLHttpRequest.getAllResponseHeaders()`

以字符串的形式返回所有用 CRLF 分隔的响应头，如果没有收到响应，则返回 `null`。

`XMLHttpRequest.getResponseHeader()`

返回包含指定响应头的字符串，如果响应尚未收到或响应中不存在该报头，则返回 `null`。

`XMLHttpRequest.open()`

初始化一个请求。

`XMLHttpRequest.overrideMimeType()`

覆写由服务器返回的 MIME 类型。

`XMLHttpRequest.send()`

发送请求。如果请求是异步的（默认），那么该方法将在请求发送后立即返回。

`XMLHttpRequest.setRequestHeader()`

设置 HTTP 请求标头的值。必须在 `open()` 之后、`send()` 之前调用 `setRequestHeader()` 方法。

事件
--

`abort`

 当 request 被停止时触发，例如当程序调用 `XMLHttpRequest.abort()` 时。
 也可以使用 `onabort` 属性。

`error`

 当 request 遭遇错误时触发。
 也可以使用 `onerror` 属性

`load`

`XMLHttpRequest`请求成功完成时触发。
 也可以使用 `onload` 属性。

`loadend`

 当请求结束时触发，无论请求成功 ( `load`) 还是失败 (`abort` 或 `error`)。
 也可以使用 `onloadend` 属性。

`loadstart`

 接收到响应数据时触发。
 也可以使用 `onloadstart` 属性。

`progress`

 当请求接收到更多数据时，周期性地触发。
 也可以使用 `onprogress` 属性。

`timeout`

 在预设时间内没有接收到响应时触发。
 也可以使用 `ontimeout` 属性。

规范
--

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

浏览器兼容性
------

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

参见
--

* `XMLSerializer`：将 DOM 树解析为 XML 对象
* 使用 XMLHttpRequest
* Fetch API


RTCDataChannel - Web API 接口参考

RTCDataChannel
==============

**实验性:** **这是一项实验性技术**
在将其用于生产之前，请仔细检查浏览器兼容性表格。

RTCDataChannel 接口代表在两者之间建立了一个双向数据通道的连接。

可以用 `RTCDataChannel.createDataChannel()` 或者在现有的 `RTCPeerConnection` 上用 `RTCDataChannelEvent` (en-US) 类型的 `datachannel` 事件接收，创建出 RTCDataChannel 类型的对象。

**备注：** 这个 API 在 Gecko 中被称作 DataChannel 而不是标准的'RTCDataChannel'。

属性
--

`RTCDataChannel.label` (en-US) 只读

返回一个包含有描述数据通道名字的`DOMString`。这个字段没有唯一性要求。

`RTCDataChannel.ordered` (en-US) 只读

返回一个`Boolean` (en-US)对象，表示传递信息的顺序是否有保证。

`RTCDataChannel.protocol` (en-US) 只读

返回一个包含有正在使用的子协议的名称的 `DOMString`，如果没有这样的子协议，返回""

`RTCDataChannel.id` (en-US) 只读

当`RTCDataChannel`对象被创建出来的时候，返回一个无符号 short 类型的数据，作为通道的标识 id。

`RTCDataChannel.readyState` (en-US) 只读

返回枚举类型的 RTCDataChannelState，表示数据连接的状态，有以下几种类型：

* `"connecting"` 该状态表示底层链路还未建立和激活，该状态还是由`RTCPeerConnection.createDataChannel()`生成的 datachannel 初始状态。
* `"open"` 该状态表示底层链路已经连接成功并且运行。这个状态还是由`RTCDataChannelEvent` (en-US)分发的 datachannel 的初始状态。
* `"closing"` 该状态表示底层链路已经在关闭的过程中。该状态下将不会接受新的发送任务，但是缓冲队列中的消息还是会被继续发送或者接收。
* `"closed"` 该状态表示底层链路已经完全被关闭（或者无法处于 established 状态）。

`RTCDataChannel.bufferedAmount` (en-US) 只读

返回一个`unsigned long`，表示缓冲队列中等待发送的字节数。这些数据是通过`RTCDataChannel.send()` (en-US)添加进缓冲队列但还未被发送的数据请求。注意：就算 channel 处于`closed`状态，队列中的缓存还会保持。

`RTCDataChannel.binaryType` (en-US)

是一个`DOMString` 类型，表示由链路发送的二进制数据的类型。该项的值应该为`"blob"`或者`"arraybuffer"`，默认值为`"blob"`。当值为`"blob"`的时候，使用`Blob`对象，当值为`"arraybuffer"`时，使用`ArrayBuffer`对象

`RTCDataChannel.maxPacketLifeType` 只读

是一个`unsigned short`类型，表示不可靠模式下的消息发送允许时间长度，单位为毫秒。

`RTCDataChannel.maxRetransmits` (en-US) 只读

是一个`unsigned short`类型，表示不可靠模式下消息允许尝试重发的最大次数。

`RTCDataChannel.negotiated` (en-US) 只读

是一个`Boolean` (en-US)类型，表示这个 channel 是否已经通过应用协商。

`DataChannel.reliable`
非标准
 只读

是一个`Boolean` (en-US)类型，表示这个链接能不能以非可靠模式发送消息。已经废弃的 api。

`DataChannel.stream`
非标准
 只读

和`RTCDataChannel.id` (en-US)等效，已经废弃的 api。

### 事件处理器

`RTCDataChannel.onopen` (en-US)

当接收到 `open` 事件时的事件处理器，当底层链路数据传输成功，端口状态处于 established 的时候会触发该事件。

`RTCDataChannel.onmessage` (en-US)

当接收到 `message` 事件时的事件处理器。当有数据被接收的时候会触发该事件。

`RTCDataChannel.onclose` (en-US)

当接收到 `close` 事件时候的事件处理器。当底层链路被关闭的时候会触发该事件。

`RTCDataChannel.onerror` (en-US)

当接收到 `error` 事件时候的事件处理器。当遇到错误的时候会触发该事件。

方法
--

`RTCDataChannel.close()` (en-US)

关闭 channel 的方法。这个关闭动作不是直接生效的。这个方法会将 channel 的`state` (en-US) 属性设置为`"closing"`状态，在消息队列中的消息全部发送完毕之后，channel 才会被关闭。

`RTCDataChannel.send()` (en-US)

将参数中的数据通过 channel 发送。这个数据可以是`DOMString`, `Blob`, `ArrayBuffer`或者是 `ArrayBufferView`类型。

示例
--

```js
var pc = new RTCPeerConnection();
var dc = pc.createDataChannel("my channel");

dc.onmessage = function (event) {
  console.log("received: " + event.data);
};

dc.onopen = function () {
  console.log("datachannel open");
};

dc.onclose = function () {
  console.log("datachannel close");
};
```

规范
--

| Specification |
| --- |
| WebRTC: Real-Time Communication in Browsers # rtcdatachannel |

浏览器兼容性
------

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

参见
--

* WebRTC


MessageChannel - Web API 接口参考

MessageChannel
==============

Channel Messaging API 的 **`MessageChannel`** 接口允许我们创建一个新的消息通道，并通过它的两个 `MessagePort` 属性发送数据。

**备注：** 此特性在 Web Worker 中可用

属性
--

`MessageChannel.port1` 只读

返回 channel 的 port1。

`MessageChannel.port2` 只读

返回 channel 的 port2。

构造函数
----

`MessageChannel()`

返回一个带有两个 MessagePort 属性的 MessageChannel 新对象。

示例
--

在以下代码块中，你可以看到使用 MessageChannel 构造函数实例化了一个 channel 对象。当 iframe 加载完毕，我们使用 MessagePort.postMessage 方法把一条消息和 MessageChannel.port2 传递给 iframe。handleMessage 处理程序将会从 iframe 中（使用 MessagePort.onmessage 监听事件）接收到信息，将数据其放入 innerHTML 中。

```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 基本示例（也可以在线运行示例）。

规范
--

| Specification |
| --- |
| HTML Standard # message-channels |

浏览器兼容性
------

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

参见
--

* Using channel messaging


SVGAElement - Web API 接口参考

SVGAElement
===========

SVG DOM 接口
----------

`SVGAElement`接口提供了对`<a>`元素的属性的访问，而且还提供了操作该元素的方法。

### 接口概览

|  |  |
| --- | --- |
| 作用于 | `SVGElement`、
 `SVGURIReference` (en-US)、
 `SVGTests`、
 `SVGLangSpace`、
 `SVGExternalResourcesRequired`、
 `SVGStylable` (en-US)、
 `SVGTransformable` |
| 方法 | *无* |
| 属性 | * 只读属性 `SVGAnimatedString` (en-US)
`target`
 |
| 规范文档 | SVG 1.1 (2nd Edition) |

属性
--

这个接口同样会从父级元素 \*`SVGGraphicsElement`\*继承属性，并实现 *`SVGURIReference` (en-US)* 和 *`HTMLHyperlinkElementUtils`* 中的功能。

`SVGAElement.download`

参见 `HTMLAnchorElement.download`

`SVGAElement.href`

参见 `HTMLAnchorElement.href`

`SVGAElement.hreflang`

是一个反映 `hreflang` 属性的字符串（DOMString），表示链接资源的语言种类。

`SVGAElement.ping`

是一个反映 ping 值的字符串（DOMString），包含以空格分隔开的 URL 列表，当超链接可以被跟踪时，浏览器会（在后台）发送有 PING 主体的 `POST` 的请求，一般用于追踪。

`SVGAElement.referrerPolicy`

参见 `HTMLAnchorElement.referrerPolicy`

`SVGAElement.rel`

参见 `HTMLAnchorElement.rel` (en-US)

`SVGAElement.relList`

参见`HTMLAnchorElement.relList` (en-US)

`SVGAElement.target` (en-US) 只读

它和特定元素的 `target` 属性相同

`SVGAElement.text`

是一个字符串（DOMString），作为 `Node.textContent` 属性的代名词。

`SVGAElement.type`

是一个反映 `type` 属性的字符串（DOMString），表示链接资源的 MIME 种类。

方法
--

该 `SVGAElement` 接口没有提供任何专有的方法。

示例
--

在下面的这个例子里， `<a>` 元素的 `target` 属性值是 `_blank` ，当链接被点击时，它将记录以通知是否符合条件。

```js
var linkRef = document.querySelector("a");
linkRef.target = "\_self";

linkRef.onclick = function () {
  if (linkRef.target === "\_blank") {
    console.log("BLANK!");
    linkRef.target = "\_self";
  } else {
    console.log("SORRY! not \_blank");
  }
};
```

规范
--

| Specification |
| --- |
| Scalable Vector Graphics (SVG) 2 # InterfaceSVGAElement |

浏览器兼容性
------

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

参见
--

* `<a>` SVG 元素


TextEncoderStream - Web API 接口参考

TextEncoderStream
=================

Encoding API 的 **`TextEncoderStream`** 接口将一个字符串流转换为 UTF-8 编码的字节。它与 `TextEncoder` 的流形式等价。

构造函数
----

`TextEncoderStream()`

创建一个新的 `TextEncoderStream` 对象。

属性
--

`TextEncoderStream.encoding`只读

总是返回"`utf-8`"。

`TextEncoderStream.readable`只读

返回此对象控制的 `ReadableStream` 实例。

`TextEncoderStream.writable`只读

返回此对象控制的 `WritableStream` 实例。

示例
--

* 流式传输结构化数据和 HTML 示例
* 一个使用 `TextDecoderStream` 流式处理 fetch 请求的示例。
规范
--

| Specification |
| --- |
| Encoding Standard # interface-textencoderstream |

浏览器兼容性
------

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

参见
--

* `TextDecoderStream`
* Streams API 概念
* Experimenting with the Streams API


AudioNode - Web API 接口参考

AudioNode
=========

**实验性:** **这是一项实验性技术**
在将其用于生产之前，请仔细检查浏览器兼容性表格。

![AudioNodes participating in an AudioContext create a audio routing graph.](/zh-CN/docs/Web/API/AudioNode/webaudiobasics.png)**`AudioNode`** 接口是一个处理音频的通用模块，比如一个音频源 (e.g. 一个 HTML `<audio>` or `<video>` 元素), 一个音频地址或者一个中间处理模块 (e.g. 一个过滤器如 `BiquadFilterNode`, 或一个音量控制器如 `GainNode`).

一个 `AudioNode` 既有输入也有输出。输入与输出都有一定数量的通道。*只有一个输出而没有输入的* `AudioNode` 叫做音频源。

处理多个 `AudioNode` 时，一般来说，一个模块读取它的输入，做一些处理。后输出新生成的结果。

不同的模块可以连接在一起构建一个处理图。这样一个处理图包含 `AudioContext`。每个 `AudioNode` 只有一个这样的上下文。

一个 `AudioNode` 可以作为事件的目标，所以它实现了 `EventTarget` 接口。

属性
--

`AudioNode.context` (en-US) 只读

链接到关联的 `AudioContext`，处理图中模块的上下文对象。

`AudioNode.numberOfInputs` (en-US) 只读

返回这个 node 需要的输入数量。Source nodes are defined as nodes having a `numberOfInputs` attributes with a value of `0`.

`AudioNode.numberOfOutputs` (en-US) 只读

返回这个 node 的输出数量。Destination nodes, like `AudioDestinationNode`, have a value of `0` for this attribute.

`AudioNode.channelCount` (en-US)

Represents an integer used in determining how many channels outputs must contains. Its usage and precise definition depends of the value of `AudioNode.channelCountMode`: it is ignored if the value is `"max"`, used as a maximum value for `"clamped-max"`, or used as the effective value for `"explicit"`.

`AudioNode.channelCountMode` (en-US)

Represents an enumerated value describing the way channels must be matched between the inputs and the outputs. Possible values are:

| Value | Description | Used as default for the following `AudioNode` children |
| --- | --- | --- |
| `"max"` | The number of channels is the maximum of the number of channels all connections. That implies that `channelCount` is ignored and only up-mixing happens | `GainNode`, `DelayNode` (en-US), `ScriptProcessorNode`, `ChannelSplitterNode` (en-US), `ChannelMergerNode`, `BiquadFilterNode`, `WaveShaperNode` |
| `"clamped-max"` | The number of channels is the maximum of the number of channels of all connections, *clamped* to the value of `channelCount`. | `PannerNode` (en-US), `ConvolverNode` |
| `"explicit"` | The number of channels is defined by the value of `channelCount`. | `AudioDestinationNode`, `AnalyserNode`, `DynamicsCompressorNode` |

`AudioNode.channelInterpretation` (en-US)

 Represents an enumerated value describing the meaning of the channels. This interpretation will define how the up-mixing and the down-mixing will happen.
 The possible values are `"speakers"` or `"discrete"`. In the case of `"speakers"`, the ordering of the channels have the following meaning, and the channels are often represented by a standard abbreviation:

| Value | Description |
| --- | --- |
| *Mono* | `0: M: mono` |
| *Stereo* | `0: L: left 1: R: right` |
| *Quad* | `0: L: left 1: R: right 2: SL: surround left 3: SR: surround right` |
| *5.1* | `0: L: left 1: R: right 2: C: center 3: LFE: subwoofer 4: SL: surround left 5: SR: surround right` |

When the amount of channels doesn't match between an input and an output, up- or down-mixing happens according the following rules:

| Interpretation | Input channels | Output channels | Mixing rules |
| --- | --- | --- | --- |
| `speakers` | `1` *(Mono)* | `2` *(Stereo)* | *Up-mix from mono to stereo*.The `M` input
 channel is used for both output channels (`L` and
 `R`).`output.L = input.Moutput.R = input.M` |
| `1` *(Mono)* | `4` *(Quad)* | *Up-mix from mono to quad.*The `M` input channel
 is used for non-surround output channels (`L` and
 `R`). Surround output channels (`SL` and
 `SR`) are silent.`output.L = input.Moutput.R = input.Moutput.SL = 0output.SR
= 0` |
| `1` *(Mono)* | `6` *(5.1)* | *Up-mix from mono to 5.1.*The `M` input channel
 is used for the center output channel (`C`). All the others
 (`L`, `R`, `LFE`, `SL`, and
 `SR`) are silent.`output.L = 0output.R = 0``output.C = input.Moutput.LFE = 0output.SL = 0output.SR
= 0` |
| `2` *(Stereo)* | `1` *(Mono)* | *Down-mix from stereo to mono*.Both input channels (`L`
 and `R`) are equally combined to produce the unique output
 channel (`M`).`output.M = 0.5 * (input.L + input.R)` |
| `2` *(Stereo)* | `4` *(Quad)* | *Up-mix from stereo to quad.*The `L` and
 `R` input channels are used for their non-surround respective
 output channels (`L` and `R`). Surround output
 channels (`SL` and `SR`) are silent.`output.L = input.Loutput.R = input.Routput.SL = 0output.SR
= 0` |
| `2` *(Stereo)* | `6` *(5.1)* | *Up-mix from stereo to 5.1.*The `L` and
 `R` input channels are used for their non-surround respective
 output channels (`L` and `R`). Surround output
 channels (`SL` and `SR`), as well as the center
 (`C`) and subwoofer (`LFE`) channels, are left
 silent.`output.L = input.Loutput.R = input.Routput.C = 0output.LFE
= 0output.SL = 0output.SR = 0` |
| `4` *(Quad)* | `1` *(Mono)* | *Down-mix from quad to mono*.All four input channels
 (`L`, `R`, `SL`, and `SR`)
 are equally combined to produce the unique output channel
 (`M`).`output.M = 0.25 * (input.L + input.R +` `input.SL + input.SR``)` |
| `4` *(Quad)* | `2` *(Stereo)* | *Down-mix from quad to mono*.Both left input channels
 (`L` and `SL`) are equally combined to produce the
 unique left output channel (`L`). And similarly, both right
 input channels (`R` and `SR`) are equally combined
 to produce the unique right output channel (`R`).`output.L = 0.5 * (input.L + input.SL``)``output.R = 0.5 * (input.R + input.SR``)` |
| `4` *(Quad)* | `6` *(5.1)* | *Up-mix from quad to 5.1.*The `L`,
 `R`, `SL`, and `SR` input channels are
 used for their respective output channels (`L` and
 `R`). Center (`C`) and subwoofer
 (`LFE`) channels are left silent.`output.L = input.Loutput.R = input.Routput.C = 0output.LFE
= 0output.SL = input.SLoutput.SR = input.SR` |
| `6` *(5.1)* | `1` *(Mono)* | *Down-mix from 5.1 to stereo.*The left and right, both
 surround or not, and the central channels are all mixed together. The
 surround channels are slightly attenuated and the regular lateral
 channels are power-compensated to make them count as a single channel.
 The subwoofer (`LFE`) channel is lost.`output.M = 0.7071 * (input.L + input.R) + input.C + 0.5 * (input.SL +
input.SR)` |
| `6` *(5.1)* | `2` *(Stereo)* | *Down-mix from 5.1 to stereo.*The central (`C`)
 is summed with each lateral surround channels (`SL` or
 `SR`) and mixed to each lateral channel. As it is mixed in
 two channels, it is mixed at lower power, that is they are multiplied by
 `√2/2`. The subwoofer (`LFE`) channel is lost.`output.L = input.L + 0.7071 * (input.C + input.SL)output.R =
input.R` `+ 0.7071 * (input.C + input.SR)` |
| `6` *(5.1)* | `4` *(Quad)* | *Down-mix from 5.1 to quad.*The central (`C`) is
 mixed with the lateral non-surround channels (`L` and
 `R`). As it is mixed in two channels, it is mixed at lower
 power, that is they are multiplied by `√2/2`. The surround
 channels are passed unchanged. The subwoofer (`LFE`) channel
 is lost.`output.L = input.L + 0.7071 * input.Coutput.R = input.Routput.SL
= input.SLoutput.SR = input.SR` |
| Other |
 As these are non-standard channel layout, they are handled as if
 `channelInterpretation` was set to
 `discrete`.The specification explicitly allow the
 future definition of new speakers layout. This fallback is therefore not
 future proof as the behavior of the browsers for a specific amount of
 channels may change in the future.
  |
| `discrete` | any (`x`) | any (`y`) where `x<y` | *Up-mix discrete channels.*Fill each output channel with
 its input counterpart, that is the input channel with the same index.
 Channels with no corresponding input channels are left silent.
  |
| any (`x`) | any (`y`) where `x>y` | *Down-mix discrete channels.*Fill each output channel with
 its input counterpart, that is the input channel with the same index.
 Input channels with no corresponding output channels are dropped.
  |

方法
--

*Also implements methods from the interface* `EventTarget`.

`AudioNode.connect(AudioNode)` (en-US)

允许将此节点的一个输出连接到另一个节点的一个输入。

`AudioNode.connect(AudioParam)`

允许将此节点的一个输出连接到音频参数的一个输入。

`AudioNode.disconnect()` (en-US)

允许将这个节点从另一个节点断开连接。

例子
--

规范
--

| Specification |
| --- |
| Web Audio API # AudioNode |

浏览器兼容性
------

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

相关内容
----

* Using Web Audio


WebGL - Web API 接口参考

WebGL
=====

WebGL（Web 图形库）是一个 JavaScript API，可在任何兼容的 Web 浏览器中渲染高性能的交互式 3D 和 2D 图形，而无需使用插件。WebGL 通过引入一个与 OpenGL ES 2.0 非常一致的 API 来做到这一点，该 API 可以在 HTML5 `<canvas>` 元素中使用。这种一致性使 API 可以利用用户设备提供的硬件图形加速。

目前支持 WebGL 的浏览器有：Firefox 4+, Google Chrome 9+, Opera 12+, Safari 5.1+, Internet Explorer 11+ 和 Microsoft Edge build 10240+；然而，WebGL 一些特性也需要用户的硬件设备支持。

WebGL 2 API 引入了对大部分的 OpenGL ES 3.0 功能集的支持; 它是通过`WebGL2RenderingContext`界面提供的。

`<canvas>` 元素也被 Canvas API 用于在网页上进行 2D 图形处理。

参考
--

### 标准接口

* `WebGLRenderingContext`
* `WebGL2RenderingContext`
* `WebGLActiveInfo`
* `WebGLBuffer`
* `WebGLContextEvent`
* `WebGLFramebuffer`
* `WebGLProgram`
* `WebGLQuery`
* `WebGLRenderbuffer`
* `WebGLSampler`
* `WebGLShader`
* `WebGLShaderPrecisionFormat`
* `WebGLSync` (en-US)
* `WebGLTexture`
* `WebGLTransformFeedback` (en-US)
* `WebGLUniformLocation`
* `WebGLVertexArrayObject`
### 扩展

* `ANGLE_instanced_arrays`
* `EXT_blend_minmax` (en-US)
* `EXT_color_buffer_float` (en-US)
* `EXT_color_buffer_half_float` (en-US)
* `EXT_disjoint_timer_query` (en-US)
* `EXT_float_blend`
实验性
* `EXT_frag_depth` (en-US)
* `EXT_sRGB` (en-US)
* `EXT_shader_texture_lod` (en-US)
* `EXT_texture_compression_bptc` (en-US)
* `EXT_texture_compression_rgtc` (en-US)
* `EXT_texture_filter_anisotropic` (en-US)
* `OES_element_index_uint` (en-US)
* `OES_fbo_render_mipmap` (en-US)
* `OES_standard_derivatives` (en-US)
* `OES_texture_float` (en-US)
* `OES_texture_float_linear` (en-US)
* `OES_texture_half_float` (en-US)
* `OES_texture_half_float_linear` (en-US)
* `OES_vertex_array_object`
* `OVR_multiview2` (en-US)
* `WEBGL_color_buffer_float` (en-US)
* `WEBGL_compressed_texture_astc` (en-US)
* `WEBGL_compressed_texture_atc`
* `WEBGL_compressed_texture_etc` (en-US)
* `WEBGL_compressed_texture_etc1` (en-US)
* `WEBGL_compressed_texture_pvrtc` (en-US)
* `WEBGL_compressed_texture_s3tc` (en-US)
* `WEBGL_compressed_texture_s3tc_srgb` (en-US)
* `WEBGL_debug_renderer_info` (en-US)
* `WEBGL_debug_shaders` (en-US)
* `WEBGL_depth_texture` (en-US)
* `WEBGL_draw_buffers` (en-US)
* `WEBGL_lose_context`
### 事件

* `webglcontextlost`
* `webglcontextrestored` (en-US)
* `webglcontextcreationerror` (en-US)
### 常量和类型

* WebGL 常量
* WebGL 类型
### WebGL 2

WebGL 2 是 WebGL 的一个主要更新，它通过`WebGL2RenderingContext` 接口提供。它基于 OpenGL ES 3.0，新功能包括：

* 3D textures,
* Sampler objects,
* Uniform Buffer objects,
* Sync objects (en-US),
* Query objects,
* Tranform Feedback objects (en-US),
* 部分扩展被纳入了 WebGL 2 核心： Vertex Array objects, instancing (en-US), multiple render targets, fragment depth (en-US).

另请参见博客文章 "WebGL 2 lands in Firefox" 和 webglsamples.org/WebGL2Samples 几个演示。

指南和教程
-----

下面，你将找到各种指南，以帮助你学习 WebGL 概念和教程，提供分步课程和示例。

### 指南

WebGL 中的数据

编写 WebGL 代码时使用的变量，缓冲区和其他类型数据的指南。

WebGL 最佳实践

提示和建议，以帮助你提高 WebGL 内容的质量，性能和可靠性。

使用扩展

WebGL 扩展的使用指南。

### 教程

WebGL 教程

WebGL 核心概念的初学者指南。如果你以前没有 WebGL 的经验，那么这是一个很好的起点。

### 示例

一个基础的 WebGL 的 2D 动画示例

此示例演示了单色形状的简单动画。检查的主题是适应宽高比差异，从多个着色器集合构建着色器程序的功能，以及 WebGL 绘图的基础知识。

WebGL 示例

一系列带有简短说明的实时示例展示了 WebGL 的概念和功能。根据主题和难易程度对示例进行了排序，涵盖了 WebGL 渲染上下文，着色器编程，纹理，几何图形，用户交互等。

### 高级教程

WebGL 模型视图投影

详述了常用于显示 3D 物体视图的三种核心矩阵：模型，视图和投影矩阵。

Web 中的矩阵运算

讲述 3D 变换矩阵工作原理的指南——这也能在 WebGL 计算和 CSS3 变换中派上用场。

资源
--

* Raw WebGL: WebGL 入门 Nick Desaulniers 主讲的 WebGL 基础知识。如果你从未接触过底层的图形编程，这是一个开始学习初级图形编程的好地方。
* WebGL 官网 Khronos Group 的 WebGL 官方站点。
* 学习 WebGL 一个关于如何使用 WebGL 的教程站点。
* WebGL 基础 一个关于 WebGL 的基础教程。
* WebGL 试炼 一个在线创建和分享 WebGL 的工具站点，非常适合快速创建一个原型或者体验一个成品。
* WebGL Academy 通过一个 HTML/JavaScript 编辑器来学习一个基础的 WebGl 基础知识。
* WebGL Report 一个检测浏览器是否支持 WebGL 的网站。
### 库

* glMatrix 创建高性能 WebGL 应用的 JavaScript 矩阵矢量库。
* PhiloGL 一个用于数据可视化、创意编程和游戏开发的 WebGL 库。
* Pixi.js是一种快速的开源 2D WebGL 渲染器。
* PlayCanvas是一个开源游戏引擎。
* Sylvester是一个用于处理向量和矩阵的开源库。尚未针对 WebGL 进行优化，但功能极其强大。
* three.js是一个开源的，功能齐全的 3D WebGL 库。
* Phaser是一个适用于 Canvas 和 WebGL 的浏览器游戏的快速，免费和有趣的开源框架。
* RedGL 是一个开源 3D WebGL 库。
* vtk.js 是一个 JavaScript 库，用于在浏览器中进行科学可视化。
规范
--

| Specification |
| --- |
| WebGL Specification # 5.14 |
| WebGL 2.0 Specification # 3.7 |

浏览器兼容性
------

### api.WebGLRenderingContext

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

### api.WebGL2RenderingContext

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

### 兼容性说明

不仅是浏览器，GPU 本身也需要支持该特性。比如 S3 纹理压缩 (S3TC) 只在基于图睿的 GPU 的设备上可用。大多数浏览器可以通过 `webgl` 这一上下文名称来使用 WebGL，但是旧的浏览器需要使用 `experimental-webgl`。另外，将来的 WebGL 2 只会向后兼容，其使用的上下文名称为 `webgl2` 。

### Gecko 备忘

#### WebGL 调试与检测

开始使用 Gecko 10.0，在测试中，这里有两个参数可以让你来控制 WebGL 性能：

`webgl.min_capability_mode`

一个以布尔值存储的属性。当它的值为`True`时，将会启用最小性能模式。当这个模式启用时，WebGL 将会仅提供由其标准指定的最基本的功能集和性能支持。这样可以确保你的 WebGL 代码能够在性能的设备和浏览器上正确运行。它的默认值是`False`。

`webgl.disable_extensions`

一个以布尔值存储的属性。当它的值为`True`时，会禁用所有的 WebGL 拓展。它的默认值是`False`。

参见
--

* Canvas(画布)
* 兼容性信息关于 WebGL 的扩展


StylePropertyMap - Web API 接口参考

StylePropertyMap
================

**实验性:** **这是一项实验性技术**
在将其用于生产之前，请仔细检查浏览器兼容性表格。

CSS 类型对象模型 API (en-US) 的 **`StylePropertyMap`** 接口提供了 CSS 声明块的表示，该声明块可以替代 `CSSStyleDeclaration`。

StylePropertyMapReadOnly

(en-US)

StylePropertyMap属性
--

*从其父级 `StylePropertyMapReadOnly` (en-US) 继承属性。*

方法
--

*从其父级 `StylePropertyMapReadOnly` (en-US) 继承方法。*

`StylePropertyMap.append()` (en-US)

使用给定的属性和值向 `StylePropertyMap` 添加新的 CSS 声明。

`StylePropertyMap.clear()` (en-US)

删除 `StylePropertyMap` 中的所有声明。

`StylePropertyMap.delete()` (en-US)

使用给定属性删除 CSS 声明。

`StylePropertyMap.set()` (en-US)

使用给定属性更改 CSS 声明。

规范
--

| Specification |
| --- |
| CSS Typed OM Level 1 # the-stylepropertymap |

浏览器兼容性
------

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


PositionError - Web API 接口参考

PositionError
=============

**`PositionError`** 接口表示当定位设备位置时发生错误的原因。

属性
--

*`PositionError` 接口没有继承任何属性。*

`PositionError.code` (en-US) 只读

返回无符号的、简短的错误码。下列值是可能的：

| 值 | 相关联的常量 | 描述 |
| --- | --- | --- |
| `1` | `PERMISSION_DENIED` | 地理位置信息的获取失败，因为该页面没有获取地理位置信息的权限。 |
| `2` | `POSITION_UNAVAILABLE` | 地理位置获取失败，因为至少有一个内部位置源返回一个内部错误。 |
| `3` | `TIMEOUT` | 获取地理位置超时，通过定义`PositionOptions.timeout` 来设置获取地理位置的超时时长。 |

`PositionError.message` (en-US) 只读

返回一个开发者可以理解的 `DOMString` 来描述错误的详细信息。

方法
--

**`PositionError` 接口没有实现也没有*继承任何方法。***

标准
--

| Specification |
| --- |
| Geolocation API # position\_error\_interface |

浏览器兼容性
------

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

请参见
---

* Using geolocation
* The `Geolocation` interface that use it.


TextMetrics - Web API 接口参考

TextMetrics
===========

在 canvas 中，**`TextMetrics`** 接口表示文本的尺寸，通过 `CanvasRenderingContext2D.measureText()` 方法创建。

属性
--

`TextMetrics.width` 只读

**double** 类型，使用 CSS 像素计算的内联字符串的宽度。基于当前上下文字体考虑。

`TextMetrics.actualBoundingBoxLeft` (en-US) 只读

**double** 类型，平行于基线，从`CanvasRenderingContext2D.textAlign` 属性确定的对齐点到文本矩形边界左侧的距离，使用 CSS 像素计算；正值表示文本矩形边界左侧在该对齐点的左侧。

`TextMetrics.actualBoundingBoxRight` (en-US) 只读

**double** 类型，平行于基线，从`CanvasRenderingContext2D.textAlign` 属性确定的对齐点到文本矩形边界右侧的距离，使用 CSS 像素计算。

`TextMetrics.fontBoundingBoxAscent` (en-US) 只读

**double** 类型，从`CanvasRenderingContext2D.textBaseline` 属性标明的水平线到渲染文本的所有字体的矩形最高边界顶部的距离，使用 CSS 像素计算。

`TextMetrics.fontBoundingBoxDescent` (en-US) 只读

**double** 类型，从`CanvasRenderingContext2D.textBaseline` 属性标明的水平线到渲染文本的所有字体的矩形边界最底部的距离，使用 CSS 像素计算。

`TextMetrics.actualBoundingBoxAscent` (en-US) 只读

**double** 类型，从`CanvasRenderingContext2D.textBaseline` 属性标明的水平线到渲染文本的矩形边界顶部的距离，使用 CSS 像素计算。

`TextMetrics.actualBoundingBoxDescent` (en-US) 只读

**double** 类型，从`CanvasRenderingContext2D.textBaseline` 属性标明的水平线到渲染文本的矩形边界底部的距离，使用 CSS 像素计算。

`TextMetrics.emHeightAscent` (en-US) 只读

**double** 类型，从`CanvasRenderingContext2D.textBaseline` 属性标明的水平线到线框中 *em* 方块顶部的距离，使用 CSS 像素计算。

`TextMetrics.emHeightDescent` (en-US) 只读

**double** 类型，从`CanvasRenderingContext2D.textBaseline` 属性标明的水平线到线框中 *em* 方块底部的距离，使用 CSS 像素计算。

`TextMetrics.hangingBaseline` (en-US) 只读

**double** 类型，从`CanvasRenderingContext2D.textBaseline` 属性标明的水平线到线框的 hanging 基线的距离，使用 CSS 像素计算。

`TextMetrics.alphabeticBaseline` (en-US) 只读

**double** 类型，从`CanvasRenderingContext2D.textBaseline` 属性标明的水平线到线框的 alphabetic 基线的距离，使用 CSS 像素计算。

`TextMetrics.ideographicBaseline` (en-US) 只读

**double** 类型，从 `CanvasRenderingContext2D.textBaseline` 属性标明的水平线到线框的 ideographic 基线的距离，使用 CSS 像素计算。

示例
--

### 基线说明

下面这个例子展示了 `TextMetrics` 对象所包含的基线。默认的基线是 `alphabeticBaseline`（字母基线）。参见 `CanvasRenderingContext2D.textBaseline` 属性。

#### HTML

```html
<canvas id="canvas" width="550" height="500"></canvas>
```

#### JavaScript

```js
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const baselinesAboveAlphabetic = [
  "fontBoundingBoxAscent",
  "actualBoundingBoxAscent",
  "emHeightAscent",
  "hangingBaseline",
];
const baselinesBelowAlphabetic = [
  "ideographicBaseline",
  "emHeightDescent",
  "actualBoundingBoxDescent",
  "fontBoundingBoxDescent",
];
const baselines = [...baselinesAboveAlphabetic, ...baselinesBelowAlphabetic];
ctx.font = "25px serif";
ctx.strokeStyle = "red";
baselines.forEach((baseline, index) => {
  const text = `Abcdefghijklmnop (${baseline})`;
  const textMetrics = ctx.measureText(text);
  const y = 50 + index \* 50;
  ctx.beginPath();
  ctx.fillText(text, 0, y);
  let lineY = y - Math.abs(textMetrics[baseline]);
  if (baselinesBelowAlphabetic.includes(baseline)) {
    lineY = y + Math.abs(textMetrics[baseline]);
  }
  ctx.moveTo(0, lineY);
  ctx.lineTo(550, lineY);
  ctx.stroke();
});
```

#### 结果

### 测量文本宽度

当测量一段文本的水平宽度时，由于字母倾斜/斜体导致字符的宽度可能超出其预定的宽度，因此 `actualBoundingBoxLeft` 和 `actualBoundingBoxRight` 的总和可能会比内联盒子的宽度（`width`）更大。

因此，计算 `actualBoundingBoxLeft` 和 `actualBoundingBoxRight` 的总和是一种更准确地获取文本绝对宽度的方法：

```js
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const text = "Abcdefghijklmnop";
ctx.font = "italic 50px serif";
const textMetrics = ctx.measureText(text);
console.log(textMetrics.width);
// 459.8833312988281
console.log(
  textMetrics.actualBoundingBoxRight + textMetrics.actualBoundingBoxLeft,
);
// 462.8833333333333
```

规范
--

| Specification |
| --- |
| HTML Standard # textmetrics |

浏览器兼容性
------

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

参见
--

* 创建方法在 `CanvasRenderingContext2D` 中。
* The `<canvas>` element and its associated interface, `HTMLCanvasElement`


PromiseRejectionEvent - Web API 接口参考

PromiseRejectionEvent
=====================

**`PromiseRejectionEvent`** 接口表示出现在 JavaScript `Promise`s 被 rejecte (拒绝) 时触发的事件。这些事件对遥测 (远程测试) 和调试特别的有用。

构造函数
----

`PromiseRejectionEvent()`

用给定的参数生成一个 `PromiseRejectionEvent` 事件。

属性
--

*也从它的父级`Event`继承属性。*

`PromiseRejectionEvent.promise` 只读

被 rejected 的 JavaScript `Promise` 。

`PromiseRejectionEvent.reason` (en-US) 只读

一个值或 `Object` 表明为什么 promise 被 rejected，并传递给`Promise.reject()`。

方法
--

*没有特定的方法; 从它的父级 `Event`继承方法。*

事件
--

`rejectionhandled`

在一个 JavaScript `Promise` 被 reject 时触发，在 reject 后由 promise 的 reject 处理函数处理。

`unhandledrejection`

在一个 JavaScript `Promise` 被 reject（拒绝）但是没有 reject 处理函数来处理时触发。

示例
--

```js
window.onunhandledrejection = function (e) {
  console.log(e.reason);
};
```

规范
--

| Specification |
| --- |
| HTML Standard # the-promiserejectionevent-interface |

浏览器兼容性
------

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

参见
--

* `Promise`
* `onrejectionhandled`
* `onunhandledrejection`


GPUDevice - Web API 接口参考

GPUDevice
=========

**实验性:** **这是一项实验性技术**
在将其用于生产之前，请仔细检查浏览器兼容性表格。

WebGPU API 的 **`GPUDevice`** 接口表示一个逻辑 GPU 设备。这是访问大部分 WebGPU 功能的主要接口。

使用 `GPUAdapter.requestDevice()` (en-US) 方法请求 `GPUDevice` 对象。

EventTarget

GPUDevice实例属性
----

*从其父接口 `EventTarget` 继承属性。*

`features` (en-US)
实验性
 只读

`GPUSupportedFeatures` (en-US) 对象，其描述了由设备支持的额外功能。

`label` (en-US)
实验性

字符串，其提供了用于标识对象的标签，例如在 `GPUError` (en-US) 信息或控制台警告中。

`limits` (en-US)
实验性
 只读

`GPUSupportedLimits` (en-US) 对象，其描述了由设备支持的限制。

`lost` (en-US)
实验性
 只读

包含一个 `Promise`，该 promise 在设备的整个生命周期内一直保留待定状态，当失去设备时，会兑现为 `GPUDeviceLostInfo` (en-US)。

`queue` (en-US)
实验性
 只读

返回设备主要的 `GPUQueue` (en-US)。

实例方法
----

*从其父接口 `EventTarget` 继承方法。*

`createBindGroup()` (en-US)
实验性

基于 `GPUBindGroupLayout` (en-US) 创建一个 `GPUBindGroup` (en-US)，该组定义了一组要绑定在一起的资源，以及如何在着色阶段使用这些资源。

`createBindGroupLayout()` (en-US)
实验性

创建一个 `GPUBindGroupLayout` (en-US)，其定义了相关 GPU 资源的结构和目的，例如将在管线中使用的缓冲区，并在创建 `GPUBindGroup` (en-US) 时用作模版。

`createBuffer()` (en-US)
实验性

创建一个 `GPUBuffer` (en-US)，在其中存储用于 GPU 运算的原始数据。

`createCommandEncoder()` (en-US)
实验性

创建一个 `GPUCommandEncoder` (en-US)，用于将要发给 GPU 的指令编码。

`createComputePipeline()` (en-US)
实验性

创建一个 `GPUComputePipeline` (en-US)，可以控制计算着色阶段，并用于 `GPUComputePassEncoder` (en-US)。

`createComputePipelineAsync()` (en-US)
实验性

返回一个 `Promise`，会兑现一个 `GPUComputePipeline` (en-US)，一旦管线可以在没有任何停滞的情况下使用，其可以控制计算着色阶段，并用于 `GPUComputePassEncoder` (en-US)。

`createPipelineLayout()` (en-US)
实验性

创建一个 `GPUPipelineLayout` (en-US)，其定义了管线使用的 `GPUBindGroupLayout` (en-US)。在指令编码期间，与管线一起使用的 `GPUBindGroup` (en-US) 必须具有兼容的 `GPUBindGroupLayout` (en-US)。

`createQuerySet()` (en-US)
实验性

创建一个 `GPUQuerySet` (en-US)，其可以用于录制通道中的查询结果，例如例如遮挡或时间戳查询。

`createRenderBundleEncoder()` (en-US)
实验性

创建一个 `GPURenderBundleEncoder` (en-US)，其可用于预先录制指令的 bundle。可以根据需要多次，通过 `executeBundles()` (en-US) 方法在 `GPURenderPassEncoder` (en-US) 中重复使用。

`createRenderPipeline()` (en-US)
实验性

创建一个 `GPURenderPipeline` (en-US)，其可以控制顶点或片元着色器阶段，并用于 `GPURenderPassEncoder` (en-US) 或 `GPURenderBundleEncoder` (en-US)。

`createRenderPipelineAsync()` (en-US)
实验性

返回一个 `Promise`，会兑现一个 `GPURenderPipeline` (en-US)，一旦管线可以在没有任何停滞的情况下使用，其可以控制顶点或片元着色器阶段，并用于 `GPURenderPassEncoder` (en-US) 或 `GPURenderBundleEncoder` (en-US)。

`createSampler()` (en-US)
实验性

创建一个 `GPUSampler` (en-US)，其控制着色器如何转换并过滤纹理资源数据。

`createShaderModule()` (en-US)
实验性

创建一个 `GPUShaderModule` (en-US)，其用 WGSL 源码字符串创建。

`createTexture()` (en-US)
实验性

创建一个 `GPUTexture` (en-US)，在其中存储用于 GPU 渲染操作的纹理数据。

`destroy()` (en-US)
实验性

销毁设备，防止对它进行进一步操作。

`importExternalTexture()` (en-US)
实验性

将 `HTMLVideoElement` 作为输入，并返回一个 `GPUExternalTexture` (en-US) 包装器对象，其中包含可用于 GPU 渲染操作的视频快照。

`popErrorScope()` (en-US)
实验性

从错误范围堆栈中弹出一个现有的 GPU 错误作用域，并返回一个 Promise，会兑现为一个对象（`GPUInternalError` (en-US)、`GPUOutOfMemoryError` (en-US) 或 `GPUValidationError` (en-US)），描述作用域中捕获的第一个错误，如果没有发生错误，则为 `null`。

`pushErrorScope()` (en-US)
实验性

将新的 GPU 错误作用域推入到设备的错误作用域栈上，允许你捕获特定类型的错误。

事件
--

`uncapturederror` (en-US)
实验性

当抛出 GPU 错误作用域未观察到的错误时触发，以提供报告意外错误的方式。已知的错误情况应使用 `pushErrorScope()` (en-US) 和 `popErrorScope()` (en-US) 处理。

示例
--

```js
async function init() {
  if (!navigator.gpu) {
    throw Error("WebGPU not supported.");
  }

  const adapter = await navigator.gpu.requestAdapter();
  if (!adapter) {
    throw Error("Couldn't request WebGPU adapter.");
  }

  const device = await adapter.requestDevice();

  const shaderModule = device.createShaderModule({
    code: shaders,
  });

  //...
}
```

有关 `GPUDevice` 使用的更多示例，请参阅上面列出的每个成员页面和以下的演示网站：

* 基础的计算示例
* 基础的渲染示例
* WebGPU 示例
规范
--

| Specification |
| --- |
| WebGPU # gpudevice |

浏览器兼容性
------

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

参见
--

* WebGPU API


DOMError - Web API 接口参考

DOMError
========

**已弃用:** 不再推荐使用该特性。虽然一些浏览器仍然支持它，但也许已从相关的 web 标准中移除，也许正准备移除或出于兼容性而保留。请尽量不要使用该特性，并更新现有的代码；参见本页面底部的兼容性表格以指导你作出决定。请注意，该特性随时可能无法正常工作。

**`DOMError`** 接口描述一个错误对象，该对象包含一个错误的名字。

属性
--

`DOMError.name` 只读

返回一个代表一个错误类型名称的 `DOMString` (见下文).

`DOMError.message` 只读

返回一个代表与给定错误类型名称有关的信息或描述`DOMString`

Error 类型
--------

| Type | Description |
| --- | --- |
| `IndexSizeError` | The index is not in the allowed range (e.g. thrown in a `range` object). 索引不在允许的范围内 |
| `HierarchyRequestError` | The node tree hierarchy is not correct. 节点树层次结构是不正确的。 |
| `WrongDocumentError` | The object is in the wrong `document`. 对象是错误的 |
| `InvalidCharacterError` | The string contains invalid characters. 字符串包含无效字符。 |
| `NoModificationAllowedError` | The object can not be modified. 对象不能被修改。 |
| `NotFoundError` | The object can not be found here. 对象不能在这里被找到。 |
| `NotSupportedError` | The operation is not supported 不支持的操作 |
| `InvalidStateError` | The object is in an invalid state. 对象是一个无效的状态。 |
| `SyntaxError` | The string did not match the expected pattern. 字符串不匹配预期的模式 |
| `InvalidModificationError` | The object can not be modified in this way. 对象不能以这种方式被修改 |
| `NamespaceError` | The operation is not allowed by Namespaces in XML 操作在 XML 命名空间内是不被允许的 |
| `InvalidAccessError` | The object does not support the operation or argument. 对象不支持这种操作或参数。 |
| `TypeMismatchError` | The type of the object does not match the expected type. 对象的类型不匹配预期的类型。 |
| `SecurityError` | The operation is insecure. 此操作是不安全的。 |
| `NetworkError` | A network error occurred. 发生网络错误 |
| `AbortError` | The operation was aborted. 操作被中止 |
| `URLMismatchError` | The given URL does not match another URL. 给定的 URL 不匹配另一个 URL。 |
| `QuotaExceededError` | The quota has been exceeded. 已经超过给定配额。 |
| `TimeoutError` | The operation timed out. 操作超时。 |
| `InvalidNodeTypeError` | The node is incorrect or has an incorrect ancestor for this operation. 这个操作的 节点或节点祖先 是不正确的 |
| `DataCloneError` | The object can not be cloned. 对象不能克隆。 |

浏览器兼容性
------

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

参见
--

* `DOMException`


Resize Observer API - Web API 接口参考

Resize Observer API
===================

Resize Observer API 提供了一种高性能的机制，通过该机制，代码可以监视元素的大小更改，并且每次大小更改时都会向观察者传递通知。

概念和使用
-----

存在大量的响应式设计（以及其他相关）技术，它们可以响应元素大小的变化，但是以前，它们的实现常常很笨拙或者说生硬。

举个例子，当视口更改大小时，媒体查询 / `window.matchMedia` 非常适合在特定点更新布局，但是如果要响应于特定元素的大小更改而更改布局，该元素又不是外部容器时，该怎么办？

为此，一种有限的解决方案是监听对适当事件的更改，该事件会提示你对更改大小感兴趣的元素（例如 window resize 事件），然后找出该元素之后新的尺寸或其他功能，例如，使用`Element.getBoundingClientRect` 或者`Window.getComputedStyle`，来调整大小。

这样的解决方案仅适用于有限的场景，对性能不利（不断调用上述方法会导致性能严重下降），并且在不更改浏览器窗口大小的情况下通常不起作用。

Resize Observer API 提供了一种解决此类问题的解决方案，此外，它还使你能够轻松观察和响应元素内容或边框的大小变化，并以高效的方式做出响应。它为 Web 平台中经常讨论的，缺乏元素查询提供了 JavaScript 解决方案。

用法很简单，并且与其他观察者（例如 Performance Observer 或者 Intersection Observer）几乎相同——你可以使用 `ResizeObserver()` 构造函数创建一个新的 `ResizeObserver`，然后使用 `ResizeObserver.observe()` 使其寻找特定元素大小的更改。每次更改大小时，构造函数中设置的回调函数便会运行，从而提供对新尺寸的访问，并允许你根据需要执行任何操作。

接口
--

`ResizeObserver`

提供注册新观察者以及启动和停止观察元素的能力。

`ResizeObserverEntry`

描述已调整大小的单个元素，标识该元素及其新大小。

示例
--

你可以在我们的 GitHub 存储库中找到几个简单的示例：

* resize-observer-border-radius.html（源码）：一个带有绿色框的简单示例，其大小为视口大小的百分比。更改视口大小时，框的圆角将根据框的大小成比例地变化。我们可以通过 `border-radius` 的百分比来实现，但这很快就会导致丑陋的椭圆形角，而上述解决方案为你提供了随盒子大小缩放的漂亮的圆角。
* resize-observer-text.html (源码): 这里我们使用 resize observer 来改变 `font-size`，标题和段落的值随着滑块值的改变而改变，导致包含的<div>改变宽度。这表明你可以响应元素大小的变化，即使它们与视口无关。

代码通常将遵循这种模式（取自 resize-observer-border-radius.html）：

```js
const resizeObserver = new ResizeObserver((entries) => {
  const calcBorderRadius = (size1, size2) =>
    `${Math.min(100, size1 / 10 + size2 / 10)}px`;

  for (const entry of entries) {
    if (entry.borderBoxSize) {
      entry.target.style.borderRadius = calcBorderRadius(
        entry.borderBoxSize[0].inlineSize,
        entry.borderBoxSize[0].blockSize,
      );
    } else {
      entry.target.style.borderRadius = calcBorderRadius(
        entry.contentRect.width,
        entry.contentRect.height,
      );
    }
  }
});

resizeObserver.observe(document.querySelector("div"));
```

规范
--

| Specification |
| --- |
| Resize Observer # resize-observer-interface |

浏览器兼容性
------

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

参见
--

* ResizeObserver: It’s Like document.onresize for Elements


WebGLSampler - Web API 接口参考

WebGLSampler
============

**实验性:** **这是一项实验性技术**
在将其用于生产之前，请仔细检查浏览器兼容性表格。

WebGL 2 API 的 **`WebGLSampler`** 接口存储一系列采样参数，供 `WebGLTexture` 在着色器中访问。

当使用 `WebGLSampler` 对象时，有以下 `WebGL2RenderingContext` 相关方法：

* `WebGL2RenderingContext.createSampler()`
* `WebGL2RenderingContext.deleteSampler()` (en-US)
* `WebGL2RenderingContext.isSampler()` (en-US)
* `WebGL2RenderingContext.bindSampler()` (en-US)
* `WebGL2RenderingContext.getSamplerParameter()` (en-US)
示例
--

### 创建 `WebGLSampler` 对象

在本例中，`gl` 必须是一个 `WebGL2RenderingContext` 对象。因为 `WebGLSampler` 在 WebGL 1 中是不可用的。

```js
var sampler = gl.createSampler();
```

规范
--

| Specification |
| --- |
| WebGL 2.0 Specification # 3.3 |

浏览器兼容性
------

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


CSSSupportsRule - Web API 接口参考

CSSSupportsRule
===============

该 **`CSSSupportsRule`** 接口描述了代表一个 CSS 对象`@supports` at-rule. 它实现了 `CSSConditionRule` 接口，因此 `CSSRule 指定规则` 和`CSSGroupingRule` 用一个类型值接口 `12` (`CSSRule.SUPPORTS_RULE`).

句法
--

该语法使用所描述的WebIDL 格式。
```

接口 CSSSupportsRule : CSSConditionRule {
}
```

性能
--

作为`CSSConditionRule` 因此一个 `CSSRule 指定规则` and 和一`CSSGroupingRule`, `CSSSupportsRule` 还实现了，这些接口的属性。它没有特定的属性

方法
--

作为`CSSConditionRule` 因此一个 `CSSRule 指定规则`和`CSSGroupingRule`, `CSSSupportsRule` 也实现了这个接口的方法。他没有具体属性的方法

规范
--

| Specification |
| --- |
| CSS Conditional Rules Module Level 3 # the-csssupportsrule-interface |

游览器兼容性
------

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

See also
--------

* `@supports`


Position - Web API 接口参考

Position
========

**`Position`** 接口表示在给定的时间的相关设备的位置。这个位置，用一个`Coordinates`对象表示，包括设备在地球上的二维位置，但也可以包括设备的海拔和速度。

属性
--

*`Position`接口没有继承任何属性。*

`Position.coords` 只读

返回一个定义了当前位置的`Coordinates` 对象。

`Position.timestamp` (en-US) 只读

返回一个时间戳`DOMTimeStamp`，这个时间戳表示获取到的位置的时间。

方法
--

**`Position` 接口没有实现也没有*继承任何方法。***

规范
--

| Specification |
| --- |
| Geolocation API # position\_interface |

浏览器兼容性
------

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

参阅
--

* 使用地理位置定位
* 使用它的`Geolocation`接口。


PerformanceEntry - Web API 接口参考

PerformanceEntry
================

**`PerformanceEntry`** 对象代表了 performance 时间列表中的单个 metric 数据。每一个 *performance entry 都可以在应用运行过程中通过手动构建* *`mark` (en-US)* 或者 *`measure` (en-US)* (例如调用 `mark()` 方法) 生成。此外，Performance entries 在资源加载的时候，也会被动生成（例如图片、script、css 等资源加载）

Note: Performance 对象暴露给了 `Window` 和 `Worker`. 同时该对象扩展了几个其他对象的属性，包括 `PerformanceMark` (en-US), `PerformanceMeasure` (en-US), `PerformanceFrameTiming`, `PerformanceNavigationTiming` 以及 `PerformanceResourceTiming`.

Properties
----------

`PerformanceEntry.name` 只读

`DOMString` 该 performance entry 的名字

`PerformanceEntry.entryType` 只读

`DOMString` 代表所上报的 performance metric 的 entryType 类型，例如 "mark". 可以通过 `entryType` 查阅完整的 entryType type 类型。

`PerformanceEntry.startTime` (en-US) 只读

`DOMHighResTimeStamp` 此为 metric 上报时的时间

`PerformanceEntry.duration` (en-US) 只读

`DOMHighResTimeStamp` 该事件的耗时

Methods
-------

`PerformanceEntry.toJSON()` (en-US)

返回 `PerformanceEntry` 对象的 JSON 格式数据

Example
-------

以下例子检查了当前浏览器所支持的所有 `PerformanceEntry` 属性，每个属性的检查结果都会通过 console 打印出来

```js
function print\_PerformanceEntries() {
  // Use getEntries() to get a list of all performance entries
  var p = performance.getEntries();
  for (var i = 0; i < p.length; i++) {
    console.log("PerformanceEntry[" + i + "]");
    print\_PerformanceEntry(p[i]);
  }
}
function print\_PerformanceEntry(perfEntry) {
  var properties = ["name", "entryType", "startTime", "duration"];

  for (var i = 0; i < properties.length; i++) {
    // check each property
    var supported = properties[i] in perfEntry;
    if (supported) {
      var value = perfEntry[properties[i]];
      console.log("... " + properties[i] + " = " + value);
    } else {
      console.log("... " + properties[i] + " = NOT supported");
    }
  }
}
```

Specifications
--------------

| Specification |
| --- |
| Performance Timeline # dom-performanceentry |

Browser compatibility
---------------------

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


CanvasRenderingContext2D - Web API 接口参考

CanvasRenderingContext2D
========================

**`CanvasRenderingContext2D`** 接口是 Canvas API 的一部分，可为 `<canvas>` 元素的绘图表面提供 2D 渲染上下文。它用于绘制形状，文本，图像和其他对象。

请参阅侧边栏和下方的界面属性和方法。Canvas 教程提供了更多的信息，例子和资源。

基础示例
----

要获得 `CanvasRenderingContext2D` 实例，你必须首先具有 HTML `<canvas>` 元素才能使用：

```html
<canvas id="my-house" width="300" height="300"></canvas>
```

要获取画布的 2D 渲染上下文，请在 `<canvas>` 元素上调用 `getContext()`，并提供 `'2d'` 作为参数：

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

有了上下文，你就可以绘制任何喜欢的东西。此代码绘制了一个房子：

```js
// Set line width
ctx.lineWidth = 10;

// Wall
ctx.strokeRect(75, 140, 150, 110);

// Door
ctx.fillRect(130, 190, 40, 60);

// Roof
ctx.beginPath();
ctx.moveTo(50, 140);
ctx.lineTo(150, 60);
ctx.lineTo(250, 140);
ctx.closePath();
ctx.stroke();
```

生成的图形如下所示：

绘制矩形
----

以下是 3 个绘制矩形位图的方法。

`CanvasRenderingContext2D.clearRect()`

设置指定矩形区域内（以点 *(x, y)* 为起点，范围是 *(width, height)*）所有像素变成透明，并擦除之前绘制的所有内容。

`CanvasRenderingContext2D.fillRect()`

绘制填充矩形，矩形的起点在 *(x, y)* 位置，矩形的尺寸是 *width* 和 *height*。

`CanvasRenderingContext2D.strokeRect()`

在 canvas 中，使用当前的笔触样式，描绘一个起点在 *(x, y)*、宽度为 *w*、高度为 *h* 的矩形。

绘制文本
----

下面是绘制文本的方法。参见 `TextMetrics` 对象获取文本属性。

`CanvasRenderingContext2D.fillText()`

在 (x,y) 位置绘制（填充）文本。

`CanvasRenderingContext2D.strokeText()`

在 (x,y) 位置绘制（描边）文本。

`CanvasRenderingContext2D.measureText()`

返回 `TextMetrics` 对象。

线型
--

下面的方法和属性控制如何绘制线。

`CanvasRenderingContext2D.lineWidth`

线的宽度。默认 `1.0`

`CanvasRenderingContext2D.lineCap`

线末端的类型。允许的值：`butt`（默认）、`round`、`square`。

`CanvasRenderingContext2D.lineJoin`

定义两线相交拐点的类型。允许的值：`round`、`bevel`、`miter`（默认）。

`CanvasRenderingContext2D.miterLimit`

斜接面限制比例。默认 `10`。

`CanvasRenderingContext2D.getLineDash()`

返回当前线段样式的数组，数组包含一组数量为偶数的非负数数字。

`CanvasRenderingContext2D.setLineDash()`

设置当前的线段样式。

`CanvasRenderingContext2D.lineDashOffset`

描述在哪里开始绘制线段。

文本样式
----

下面的属性控制如何设计文本。

`CanvasRenderingContext2D.font`

字体设置。默认值 `10px sans-serif`。

`CanvasRenderingContext2D.textAlign`

文本对齐设置。允许的值：`start`（默认）、`end`、`left`、`right` 或 `center`。

`CanvasRenderingContext2D.textBaseline`

基线对齐设置。允许的值：`top`、`hanging`、`middle`、`alphabetic`（默认）、`ideographic`、`bottom`。

`CanvasRenderingContext2D.direction`

文本的方向。允许的值：`ltr`、`rtl`、`inherit`（默认）。

填充和描边样式
-------

填充设计用于图形内部的颜色和样式，描边设计用于图形的边线。

`CanvasRenderingContext2D.fillStyle`

图形内部的颜色和样式。默认 `#000`（黑色）。

`CanvasRenderingContext2D.strokeStyle`

图形边线的颜色和样式。默认 `#000`（黑色）。

渐变和图案
-----

`CanvasRenderingContext2D.createLinearGradient()`

创建一个沿着参数坐标指定的线的线性渐变。

`CanvasRenderingContext2D.createRadialGradient()`

创建一个沿着参数坐标指定的线的放射性性渐变。

`CanvasRenderingContext2D.createPattern()`

使用指定的图片创建图案。通过 repetition 变量指定的方向上重复源图片。此方法返回 `CanvasPattern` 对象。

阴影
--

`CanvasRenderingContext2D.shadowBlur`

描述模糊效果。默认 `0`。

`CanvasRenderingContext2D.shadowColor`

阴影的颜色。默认 fully-transparent black。

`CanvasRenderingContext2D.shadowOffsetX`

阴影水平方向的偏移量。默认 0。

`CanvasRenderingContext2D.shadowOffsetY`

阴影垂直方向的偏移量。默认 0。

路径
--

下面的方法用来操作对象的路径。

`CanvasRenderingContext2D.beginPath()`

清空子路径列表开始一个新的路径。当你想创建一个新的路径时，调用此方法。

`CanvasRenderingContext2D.closePath()`

使笔点返回到当前子路径的起始点。它尝试从当前点到起始点绘制一条直线。如果图形已经是封闭的或者只有一个点，那么此方法不会做任何操作。

`CanvasRenderingContext2D.moveTo()`

将一个新的子路径的起始点移动到 (x，y) 坐标。

`CanvasRenderingContext2D.lineTo()`

使用直线连接子路径的最后的点到 (x，y) 坐标。

`CanvasRenderingContext2D.bezierCurveTo()`

添加一个 3 次贝赛尔曲线路径。该方法需要三个点。第一、第二个点是控制点，第三个点是结束点。起始点是当前路径的最后一个点，绘制贝赛尔曲线前，可以通过调用 `moveTo()` 进行修改。

`CanvasRenderingContext2D.quadraticCurveTo()`

添加一个 2 次贝赛尔曲线路径。

`CanvasRenderingContext2D.arc()`

绘制一段圆弧路径，圆弧路径的圆心在 *(x, y)* 位置，半径为 *r*，根据 *anticlockwise*（默认为顺时针）指定的方向从 *startAngle* 开始绘制，到 *endAngle* 结束。

`CanvasRenderingContext2D.arcTo()`

根据控制点和半径绘制圆弧路径，使用当前的描点（前一个 moveTo 或 lineTo 等函数的止点）。根据当前描点与给定的控制点 1 连接的直线，和控制点 1 与控制点 2 连接的直线，作为使用指定半径的圆的**切线**，画出两条切线之间的弧线路径。

`CanvasRenderingContext2D.ellipse()`

添加一个椭圆路径，椭圆的圆心在（x,y）位置，半径分别是 *radiusX* 和 *radiusY*，按照 *anticlockwise*（默认顺时针）指定的方向，从 *startAngle* 开始绘制，到 *endAngle* 结束。

`CanvasRenderingContext2D.rect()`

创建一个矩形路径，矩形的起点位置是 *(x, y)*，尺寸为 *width* 和 *height*。

绘制路径
----

`CanvasRenderingContext2D.fill()`

使用当前的样式填充子路径。

`CanvasRenderingContext2D.stroke()`

使用当前的样式描边子路径。

`CanvasRenderingContext2D.drawFocusIfNeeded()`

如果给定的元素获取了焦点，那么此方法会在当前的路径绘制一个焦点。

`CanvasRenderingContext2D.scrollPathIntoView()`

将当前或给定的路径滚动到窗口。

`CanvasRenderingContext2D.clip()`

从当前路径创建一个剪切路径。在 **clip()** 调用之后，绘制的所有信息只会出现在剪切路径内部。例如：参见 Canvas 教程中的剪切路径。

`CanvasRenderingContext2D.isPointInPath()`

判断当前路径是否包含检测点。

`CanvasRenderingContext2D.isPointInStroke()`

判断检测点是否在路径的描边线上。

变换
--

在 `CanvasRenderingContext2D` 渲染背景中的对象会有一个当前的变换矩阵，一些方法可以对其进行控制。当创建当前的默认路径，绘制文本、图形和 `Path2D` 对象的时候，会应用此变换矩阵。下面列出的方法保持历史和兼容性的原因，是为了 `DOMMatrix` 对象现在能够应用于大部分 API，将来会被替换。

`CanvasRenderingContext2D.rotate()`

在变换矩阵中增加旋转，角度变量表示一个顺时针旋转角度并且用弧度表示。

`CanvasRenderingContext2D.scale()`

根据 x 水平方向和 y 垂直方向，为 canvas 单位添加缩放变换。

`CanvasRenderingContext2D.translate()`

通过在网格中移动 canvas 和 canvas 原点 x 水平方向、原点 y 垂直方向，添加平移变换。

`CanvasRenderingContext2D.transform()`

使用方法参数描述的矩阵多次叠加当前的变换矩阵。

`CanvasRenderingContext2D.setTransform()`

重新设置当前的变换为单位矩阵，并使用同样的变量调用 **transform()** 方法。

`CanvasRenderingContext2D.resetTransform()`

使用单位矩阵重新设置当前的变换。

合成
--

`CanvasRenderingContext2D.globalAlpha`

在合成到 canvas 之前，设置图形和图像透明度的值。默认 `1.0`（不透明）。

`CanvasRenderingContext2D.globalCompositeOperation`

通过 `globalAlpha` 应用，设置如何在已经存在的位图上绘制图形和图像。

绘制图像
----

`CanvasRenderingContext2D.drawImage()`

绘制指定的图片。该方法有多种格式，提供了很大的使用灵活性。

像素控制
----

参见 `ImageData` 对象。

`CanvasRenderingContext2D.createImageData()`

使用指定的尺寸，创建一个新的、空白的 `ImageData` 对象。所有的像素在新对象中都是透明的。

`CanvasRenderingContext2D.getImageData()`

返回一个 `ImageData` 对象，用来描述 canvas 区域隐含的像素数据，这个区域通过矩形表示，起始点为 *(sx, sy)*、宽为 *sw*、高为 *sh*。

`CanvasRenderingContext2D.putImageData()`

将数据从已有的 `ImageData` 绘制到位图上。如果提供了脏矩形，只能绘制矩形的像素。

图像平滑
----

`CanvasRenderingContext2D.imageSmoothingEnabled`

图像平滑的方式；如果禁用，缩放时，图像不会被平滑处理。

canvas 状态
---------

**CanvasRenderingContext2D** 渲染环境包含了多种绘图的样式状态（属性有线的样式、填充样式、阴影样式、文本样式）。下面的方法会帮助你使用这些状态：

`CanvasRenderingContext2D.save()`

使用栈保存当前的绘画样式状态，你可以使用 **restore()** 恢复任何改变。

`CanvasRenderingContext2D.restore()`

恢复到最近的绘制样式状态，此状态是通过 **save()** 保存到“状态栈”中最新的元素。

`CanvasRenderingContext2D.canvas`

对 `HTMLCanvasElement` 只读的反向引用。如果和 `<canvas>` 元素没有联系，可能为 `null`。

规范
--

| Specification |
| --- |
| HTML Standard # 2dcontext |

浏览器兼容性
------

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

参见
--

* `HTMLCanvasElement`
* `<canvas>`


ExtendableEvent - Web API 接口参考

ExtendableEvent
===============

作为 service worker 生命周期的一部分，**`ExtendableEvent`** 接口延长了在全局范围上 `install` (en-US) 和 `activate` (en-US) 事件的生命周期。这样可以确保在升级数据库架构并删除过时的 caches 之前，不会调度任何函数事件（如`FetchEvent`）。如果在`ExtendableEvent`处理程序之外调用`waitUntil()`，浏览器应该抛出一个`InvalidStateError`；还要注意，多个调用将堆积起来，结果 promises 将添加到extend lifetime promises.

**备注：** 上述段落中描述的行为在 firefox 43 中得到了修复（参见 Firefox bug 1180274）。

此接口继承自`Event`接口。

**备注：** 只有当全局范围是 `ServiceWorkerGlobalScope` 时，此接口才可用。当它是一个 `Window` 或其他类型 worker 的作用域时，它不可用。

构造函数
----

`ExtendableEvent()` (en-US)

创建新的`ExtendableEvent`对象。

特性
--

不实现任何特定属性，但从其父级事件继承属，*`Event`*。

方法
--

*从他的父辈继承，`Event`。*

`ExtendableEvent.waitUntil()`

延长事件的生存期。它将在 service worker 的 `install` (en-US) 和 `activate` (en-US) 事件中被调用。

实例
--

代码片段来自service worker prefetch sample (查看 prefetch example live.)。代码在`ServiceWorkerGlobalScope.oninstall`中调用`ExtendableEvent.waitUntil()`，延迟将`ServiceWorkerRegistration.installing` (en-US) Worker 视为已安装，直到传递的 promise resolve(在所有资源都已被提取和缓存的情况，或者发生任何异常时的问题.)

代码段还显示了对 service worker 使用的缓存进行版本控制的最佳实践。虽然在这个例子中只有一个缓存，但是相同的方法可以用于多个缓存。它将缓存的速记标识符映射到特定的、版本化的缓存名称。

**备注：** 在 chrome 中，日志记录语句通过 chrome://service worker internals 访问的相关服务工作者的“inspect”接口可见。

```js
var CACHE\_VERSION = 1;
var CURRENT\_CACHES = {
  prefetch: "prefetch-cache-v" + CACHE\_VERSION,
};

self.addEventListener("install", function (event) {
  var urlsToPrefetch = [
    "./static/pre\_fetched.txt",
    "./static/pre\_fetched.html",
    "https://www.chromium.org/\_/rsrc/1302286216006/config/customLogo.gif",
  ];

  console.log(
    "Handling install event. Resources to pre-fetch:",
    urlsToPrefetch,
  );

  event.waitUntil(
    caches
      .open(CURRENT\_CACHES["prefetch"])
      .then(function (cache) {
        cache
          .addAll(
            urlsToPrefetch.map(function (urlToPrefetch) {
              return new Request(urlToPrefetch, { mode: "no-cors" });
            }),
          )
          .then(function () {
            console.log("All resources have been fetched and cached.");
          });
      })
      .catch(function (error) {
        console.error("Pre-fetching failed:", error);
      }),
  );
});
```

**备注：** 在获取资源时，如果有可能资源是由不支持 CORS 的服务器提供的，那么使用 `{mode: 'no-cors'}` 非常重要。在本例中， www.chromium.org 不支持 CORS。

规范
--

| Specification |
| --- |
| Service Workers # extendableevent-interface |

浏览器兼容性
------

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

参见
--

* 使用 Service Worker
* Service worker 基本代码示例
* 使用 web worker


CSSConditionRule - Web API 接口参考

CSSConditionRule
================

**CSSConditionRule** 对象表示单个条件 CSS 规则，由条件和语句块组成。继承至 `CSSGroupingRule`.

从它派生的两个对象 : `CSSMediaRule` and `CSSSupportsRule`.

Syntax
------

The syntax is described using the WebIDL format.
```

interface CSSConditionRule : CSSGroupingRule {
    attribute DOMString conditionText;
}
```

Properties
----------

The `CSSConditionRule` derives from `CSSRule`, `CSSGroupingRule` and inherits all properties of these classes. It has one specific property:

`CSSConditionRule.conditionText` (en-US)

Represents the text of the condition of the rule.

Methods
-------

The `CSSConditionRule` derives from `CSSRule`, `CSSGroupingRule` and inherits all methods of these classes. It has no specific property of its own.

Specifications
--------------

| Specification |
| --- |
| CSS Conditional Rules Module Level 3 # the-cssconditionrule-interface |

Browser compatibility
---------------------

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

See also
--------

* Using dynamic styling information


FileSystemHandle - Web API 接口参考

FileSystemHandle
================

**安全上下文:** 此项功能仅在一些支持的浏览器的安全上下文（HTTPS）中可用。

`File System Access API` 的 **`FileSystemHandle`** 接口是代表一个文件或一个目录的对象。多个句柄可以代表同一个条目。在大多数情况下，你不会直接使用 `FileSystemHandle`，而是会用到它的 `FileSystemFileHandle` 和 `FileSystemDirectoryHandle` 子接口。

基于 FileSystemHandle 的接口
-----------------------

以下是基于 FileSystemHandle 的接口的列表。

`FileSystemFileHandle`

提供一个指向文件条目的句柄。

`FileSystemDirectoryHandle`

提供一个指向目录条目的句柄。

实例属性
----

`kind` 只读

返回条目的类型。如果关联的条目是一个文件，则此值为 `'file'`，否则为 `'directory'`。

`name` 只读

返回关联的条目的名称。

实例方法
----

`isSameEntry()`

比对两个句柄以查看两者关联的条目（文件或目录）是否相符。

`queryPermission()`
实验性

查询当前句柄目前的权限状态。

`remove()`
实验性

非标准

向底层文件系统请求移除句柄所代表的的条目。

`requestPermission()`
实验性

为文件句柄请求读取或读写权限。

示例
--

### 检查类型

下面的代码允许用户在文件选择器选择一个文件，然后测试返回的句柄是一个文件还是一个目录。

```js
// 存放对文件句柄的引用
let fileHandle;

async function getFile() {
  // 打开文件选择器
  [fileHandle] = await window.showOpenFilePicker();

  if (fileHandle.kind === "file") {
    // 运行针对文件的代码
  } else if (fileHandle.kind === "directory") {
    // 运行针对目录的代码
  }
}
```

### 查询与请求权限

以下异步函数会在用户对文件句柄授予了只读或读写权限时返回 `true`，若无权限则请求权限。

```js
// fileHandle 是一个 FileSystemFileHandle
// withWrite 是一个布尔值，如果要求写入则需传入 true

async function verifyPermission(fileHandle, withWrite) {
  const opts = {};
  if (withWrite) {
    opts.mode = "readwrite";
  }

  // 检查是否已经拥有相应权限，如果是，返回 true。
  if ((await fileHandle.queryPermission(opts)) === "granted") {
    return true;
  }

  // 为文件请求权限，如果用户授予了权限，返回 true。
  if ((await fileHandle.requestPermission(opts)) === "granted") {
    return true;
  }

  // 用户没有授权，返回 false。
  return false;
}
```

### 比对条目

以下函数将单个条目与条目数组进行比对，返回包含不相符条目的新数组。

```js
function removeMatches(fileEntry, entriesArr) {
  const newArr = entriesArr.filter((entry) => !fileEntry.isSameEntry(entry));

  return newArr;
}
```

规范
--

| Specification |
| --- |
| File System Standard # api-filesystemhandle |

浏览器兼容性
------

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

参见
--

* 文件系统 API
* 文件系统访问 API：简化本地文件访问


History - Web API 接口参考

History
=======

**`History`** 接口允许操作浏览器的曾经在标签页或者框架里访问的会话历史记录。

属性
--

*`History` 接口不继承于任何属性。*

`length` 只读

返回一个整数（`Integer`），该整数表示会话历史中元素的数目，包括当前加载的页。例如，在一个新的选项卡加载的一个页面中，这个属性返回 `1`。

`scrollRestoration`

允许 Web 应用程序在历史导航上显式地设置默认滚动恢复行为。此属性可以是自动的（`auto`）或者手动的（`manual`）。

`state` 只读

返回一个表示历史堆栈顶部的状态的任意（`any`）值。这是一种不必等待 `popstate` 事件而查看状态的方式。

方法
--

*`History` 接口不继承任何方法。*

`back()`

此异步方法转到浏览器会话历史的上一页，与用户单击浏览器的 `Back` 按钮的行为相同。等价于 `history.go(-1)`。

调用此方法回到会话历史的第一页之前没有效果并且不会引发异常。

`forward()`

此异步方法转到浏览器会话历史的下一页，与用户单击浏览器的 `Forward` 按钮的行为相同。等价于 `history.go(1)`。

调用此方法超越浏览器历史记录中最新的页面没有效果并且不会引发异常。

`go()`

通过当前页面的相对位置从浏览器历史记录（会话记录）异步加载页面。比如：参数为 -1 的时候为上一页，参数为 1 的时候为下一页。当你指定了一个越界值（例如：当会话历史记录中没有之前访问的页面时，则传参的值为 -1，那么这个方法没有任何效果也不会报错。调用没有参数的 `go()` 方法或者参数值为 0 时，重新载入当前页面。Internet Explorer 允许你指定一个字符串，而不是整数，以转到历史记录列表中的特定 URL。

`pushState()`

按指定的名称和 URL（如果提供该参数）将数据 push 进会话历史栈，数据被 DOM 进行不透明处理；你可以指定任何可以被序列化的 javascript 对象。请注意，除了 Safari 所有浏览器现在都忽略了 title 参数。更多的信息，请看使用 History API。

`replaceState()`

按指定的数据、名称和 URL（如果提供该参数），更新 history 栈上最新的条目。这个数据被 DOM 进行了不透明处理。你可以指定任何可以被序列化的 javascript 对象。请注意，除了 Safari 所有浏览器现在都忽略了 title 参数。更多的信息，请看使用 History API。

规范
--

| Specification |
| --- |
| HTML Standard # the-history-interface |

浏览器兼容性
------

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

参见
--

* `Window.history` 返回当前会话的 history 状态


HTMLIFrameElement - Web API 接口参考

HTMLIFrameElement
=================

**`HTMLIFrameElement`** 接口提供了除 `HTMLElement` 之外的一些特殊属性和方法（当然也包括了继承自 `HTMLElement` 的部分）。这些方法用于操作内联 frame 元素的布局和展示。

属性
--

*继承了来自父类的属性，`HTMLElement`。*

`HTMLIFrameElement.align`
已弃用

一个 `DOMString` 指定了相对于当前上下文的对齐方式。

`HTMLIFrameElement.allowfullscreen`
实验性

一个 `Boolean` (en-US) 标识了该内联 frame 是否愿意被全屏防止。详情请参考 Using full-screen mode (en-US) 。

`HTMLIFrameElement.contentDocument` (en-US) 只读

返回一个 `Document`，该内联 frame 嵌套的浏览上下文中活跃的 document 对象。

`HTMLIFrameElement.contentWindow` 只读

返回一个 `WindowProxy`，该嵌套的浏览上下文中的 window 代理。

`HTMLIFrameElement.frameBorder`
已弃用

一个 `DOMString` 标识了是否在 frame 之间创建边框。

`HTMLIFrameElement.height` (en-US)

一个 `DOMString` 反映着 `height` HTML 属性，标识了该 frame 的高度。

`HTMLIFrameElement.longDesc`
已弃用

一个 `DOMString` 包含着该 frame 的详细描述的 URI。

`HTMLIFrameElement.marginHeight`
已弃用

一个 `DOMString` ，该 frame 的外边距高度。

`HTMLIFrameElement.marginWidth`
已弃用

一个 `DOMString` ，该 frame 的外边距宽度。

`HTMLIFrameElement.name` (en-US)

一个 `DOMString` 反映着 `name` HTML 属性，包含着用来引用该 frame 的名字。

`HTMLIFrameElement.referrerPolicy` (en-US)
实验性

一个 `DOMString` 反映着 `referrerpolicy` HTML 属性，标识了获取关联资源时要使用哪个 referrer。

`HTMLIFrameElement.sandbox`

一个 `DOMSettableTokenList` 反映着 `sandbox` HTML 属性，指示着对嵌套内容额外的限制。

`HTMLIFrameElement.scrolling`
已弃用

一个 `DOMString` 指示着浏览器是否应该为该 frame 提供滚动条。

`HTMLIFrameElement.src` (en-US)

一个 `DOMString` 反映着 `src` HTML 属性，包含被嵌入内容的地址。

`HTMLIFrameElement.srcdoc` (en-US)

一个 `DOMString` ，表示该 frame 中要显示的内容。

`HTMLIFrameElement.width` (en-US)

一个 `DOMString` 反映着 `width` HTML 属性，标识着该 frame 的宽度。

方法
--

*继承了来自父类的属性，`HTMLElement`。*

### 浏览器 API 方法

为支持浏览器`<iframe>`的需求，`HTMLIFrameElement`已经扩展了一些新的方法来让`<iframe>`有更多的能力。他们并未成为规范（参见 Browser compatibility）。

#### 导航方法

以下导航方法允许通过`<iframe>`的浏览历史进行导航。他们对于后退、前进、停止和重新加载按钮的实现而言是非常必须的。

`HTMLIFrameElement.reload()`

重新加载`<iframe>`元素内容。

`HTMLIFrameElement.stop()`

停止加载`<iframe>`元素内容。

`HTMLIFrameElement.getCanGoBack()`

指示是否可以后退。

`HTMLIFrameElement.goBack()`

改变`<iframe>`位置到上一个浏览历史记录的位置。

`HTMLIFrameElement.getCanGoForward()`

指示是否可以前进。

`HTMLIFrameElement.goForward()`

改变`<iframe>`位置到下一个浏览历史记录的位置。

#### 管理方法

这个方法集管理浏览器`<iframe>`所用的资源。它们对于实现分页浏览程序非常有用。

`HTMLIFrameElement.executeScript()`

在浏览器`<iframe>`页面加载完成后执行指定的脚本。

`HTMLIFrameElement.purgeHistory()`

清理所有与浏览器`<iframe>`有关的资源（不包括 cookie）。

`HTMLIFrameElement.setVisible()`

修改浏览器`<iframe>`的可见性。这会影响资源分配和一些函数的资源占用率，如`requestAnimationFrame`。

`HTMLIFrameElement.getVisible()`

指示当前浏览器`<iframe>`的可见性。

`HTMLIFrameElement.setActive()`

设置当前`<iframe>`为活动 frame，对进程管理器如何划分优先级有影响。

`HTMLIFrameElement.getActive()`

指示当前浏览器`<iframe>`是否为当前活动的 frame。

`HTMLIFrameElement.setInputMethodActive()`

设置当前浏览器`<iframe>`是活动的输入法编辑器窗口而其他不是。当一个顶层应用希望激活一个窗口作为输入法编辑器（如键盘）时有用。

`HTMLIFrameElement.setNfcFocus()` (en-US)

Firefox 操作系统 NFC API 的一部分，扩展了Browser API，这个集合设置浏览器`<iframe>`是否可以接收一个NFC事件。

#### 音频相关方法

以下方法允许直接控制浏览器元素的声音。

`HTMLIFrameElement.getVolume()`

获取浏览器`<iframe>`当前音量。

`HTMLIFrameElement.setVolume()`

设置浏览器`<iframe>`当前音量。

`HTMLIFrameElement.mute()`

浏览器`<iframe>`播放的所有音频静音。

`HTMLIFrameElement.unmute()`

取消浏览器`<iframe>`播放所有音频的静音。

`HTMLIFrameElement.getMuted()`

指示当前浏览器`<iframe>`当前是否被静音。

#### Search methods

New methods are provided to allow programmatic searches of browser `<iframe>`s to be carried out.

`HTMLIFrameElement.findAll()`

Searches for a string in a browser `<iframe>`'s content; if found, the first instance of the string relative to the caret position will be highlighted.

`HTMLIFrameElement.findNext()`

Highlights the next or previous instance of a search result after a `findAll()` search has been carried out.

`HTMLIFrameElement.clearMatch()`

Clears any content highlighted by `findAll()` or `findNext()`.

#### Event-related methods

In order to manage the browser `<iframe>`'s content, many new events were added (see below). The following methods are used to deal with those events:

The `<iframe>` gains support for the methods of the `EventTarget` interface

`addEventListener()`, `removeEventListener()`, and `dispatchEvent()`.

`HTMLIFrameElement.sendMouseEvent()`

Sends a `MouseEvent` to the `<iframe>`'s content.

`HTMLIFrameElement.sendTouchEvent()`

Sends a `TouchEvent` to the `<iframe>`'s content. Note that this method is available for touch enabled devices only.

`HTMLIFrameElement.addNextPaintListener()`

Defines a handler to listen for the next `MozAfterPaint` event in the browser `<iframe>`.

`HTMLIFrameElement.removeNextPaintListener()`

Removes a handler previously set with `addNextPaintListener()`.

#### Utility methods

Last, there are some utility methods, useful for apps that host a browser `<iframe>`.

`HTMLIFrameElement.download()`

Downloads a specified URL, storing it at the specified filename/path.

`HTMLIFrameElement.getContentDimensions()`

Retrieves the X and Y dimensions of the content window.

`HTMLIFrameElement.getManifest()`

Retrieves the manifest of an app loaded in the browser `<iframe>` and returns it as JSON.

`HTMLIFrameElement.getScreenshot()`

Takes a screenshot of the browser `<iframe>`'s content. This is particularly useful to get thumbnails of tabs in a tabbed browser app.

`HTMLIFrameElement.getStructuredData()`

Retrieves any structured microdata (and hCard and hCalendar microformat data) contained in the HTML loaded in the browser `<iframe>` and returns it as JSON.

`HTMLIFrameElement.zoom()`

Changes the zoom factor of the browser `<iframe>`'s content. This is particularly useful for zooming in/out on non-touch-enabled devices.

Specifications
--------------

| Specification |
| --- |
| HTML Standard # htmliframeelement |

Browser compatibility
---------------------

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

See also
--------

* The HTML element implementing this interface: `<iframe>`


AudioWorkletProcessor - Web API 接口参考

AudioWorkletProcessor
=====================

Web Audio API的 **`AudioWorkletProcessor`** 接口代表了一个 自定义的音频处理代码 `AudioWorkletNode`. 它身处于 `AudioWorkletGlobalScope` (en-US) 并运行在 Web Audio rendering 线程上。同时，一个建立在其基础上的 `AudioWorkletNode` 运行在主线程上。

构造函数
----

**备注：** `AudioWorkletProcessor` 及其子类不能通过用户提供的的代码直接实例化。它们只能随着与之相联系`AudioWorkletNode`s 的创建而被其创建再内部。其子类的构造函数将被一个可选对象调用，因此你可以执行自定义的初始化过程——详细信息请参见构造函数页面。

`AudioWorkletProcessor()` (en-US)

创建一个 `AudioWorkletProcessor` 对象的新实例。

属性
--

`port` (en-US) 只读

返回一个用于在处理程序和其所属的`AudioWorkletNode`间双向通信的 `MessagePort` 。另一端 可通过该节点的`port` (en-US) 属性使用。

方法
--

*`AudioWorkletProcessor` 接口没有定义任何自己的方法。但是，你必须提供一个 `process()` (en-US) 方法，用以处理音频流。*

事件
--

*`AudioWorkletProcessor` 接口不响应任何事件。*

使用说明
----

### Deriving classes

要自定义音频处理代码，你必须从`AudioWorkletProcessor` 接口派生一个类。这个派生类必须具有在该接口中不曾定义的`process` (en-US) 方法。该方法将被每个含有 128 样本帧的块调用并且接受输入和输出数组以及自定义的`AudioParam`s (如果它们刚被定义了) 的计算值作为参数。你可以使用输入和 音频参数值去填充输出数组，这是默认的用于使输出静音。

Optionally, if you want custom `AudioParam`s on your node, you can supply a `parameterDescriptors` (en-US) property as a *static getter* on the processor. The array of `AudioParamDescriptor`-based objects returned is used internally to create the `AudioParam`s during the instantiation of the `AudioWorkletNode`.

The resulting `AudioParam`s reside in the `parameters` (en-US) property of the node and can be automated using standard methods such as `linearRampToValueAtTime` (en-US). Their calculated values will be passed into the `process()` (en-US) method of the processor for you to shape the node output accordingly.

### 处理音频

一个创建自定义音频处理算法的步骤的实例：

1. 创建一个独立的文件;
2. 在这个文件中：
    1. Extend the `AudioWorkletProcessor` class (see "Deriving classes" section) and supply your own `process()` (en-US) method in it;
    2. Register the processor using `AudioWorkletGlobalScope.registerProcessor()` (en-US) method;
3. Load the file using `addModule()` (en-US) method on your audio context's `audioWorklet` (en-US) property;
4. Create an `AudioWorkletNode` based on the processor. The processor will be instantiated internally by the `AudioWorkletNode` constructor.
5. Connect the node to the other nodes.
例子
--

In the example below we create a custom `AudioWorkletNode` that outputs white noise.

First, we need to define a custom `AudioWorkletProcessor`, which will output white noise, and register it. Note that this should be done in a separate file.

```js
// white-noise-processor.js
class WhiteNoiseProcessor extends AudioWorkletProcessor {
  process(inputs, outputs, parameters) {
    const output = outputs[0];
    output.forEach((channel) => {
      for (let i = 0; i < channel.length; i++) {
        channel[i] = Math.random() \* 2 - 1;
      }
    });
    return true;
  }
}

registerProcessor("white-noise-processor", WhiteNoiseProcessor);
```

Next, in our main script file we'll load the processor, create an instance of `AudioWorkletNode`, passing it the name of the processor, then connect the node to an audio graph.

```js
const audioContext = new AudioContext();
await audioContext.audioWorklet.addModule("white-noise-processor.js");
const whiteNoiseNode = new AudioWorkletNode(
  audioContext,
  "white-noise-processor",
);
whiteNoiseNode.connect(audioContext.destination);
```

Specifications
--------------

| Specification |
| --- |
| Web Audio API # AudioWorkletProcessor |

Browser compatibility
---------------------

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

See also
--------

* Web Audio API
* Using the Web Audio API


ViewTransition - Web API 接口参考

ViewTransition
==============

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
**实验性:** **这是一项实验性技术**
在将其用于生产之前，请仔细检查浏览器兼容性表格。

View Transitions API 的 **`ViewTransition`** 接口表示视图过渡，并提供了在过渡到达不同状态时运行代码的功能（例如，准备运行动画，或动画完成），或跳过视图过渡。

此对象类型由 `document.startViewTransition()` 方法返回。当调用 `startViewTransition()` 时，将按照视图过渡过程中所述的步骤序列进行。这也解释了不同的 Promise 何时兑现。

实例属性
----

`ViewTransition.finished`
实验性

一个在过渡动画完成后兑现的 `Promise`，新的页面视图对用户可见且可交互。

`ViewTransition.ready`
实验性

一个在伪元素树创建且过渡动画即将开始时兑现的 `Promise`。

`ViewTransition.updateCallbackDone`
实验性

当 `document.startViewTransition()` 的回调返回的 `Promise` 兑现时，该 `Promise` 也会兑现。

实例方法
----

`skipTransition()`
实验性

跳过视图过渡的动画部分，但不会跳过运行 `document.startViewTransition()` 的回调，该回调会更新 DOM。

示例
--

在下面的示例中，`ViewTransition.ready` 用于触发从用户点击位置开始的自定义圆形揭示视图过渡，动画由 Web Animations API 提供。

```js
// 保存最后一次点击事件
let lastClick;
addEventListener("click", (event) => (lastClick = event));

function spaNavigate(data) {
  // 为不支持此 API 的浏览器提供回退方案：
  if (!document.startViewTransition) {
    updateTheDOMSomehow(data);
    return;
  }

  // 获取点击位置，或者回退到屏幕中间
  const x = lastClick?.clientX ?? innerWidth / 2;
  const y = lastClick?.clientY ?? innerHeight / 2;
  // 获取到最远角的距离
  const endRadius = Math.hypot(
    Math.max(x, innerWidth - x),
    Math.max(y, innerHeight - y),
  );

  // 开始一次视图过渡：
  const transition = document.startViewTransition(() => {
    updateTheDOMSomehow(data);
  });

  // 等待伪元素创建完成：
  transition.ready.then(() => {
    // 新视图的根元素动画
    document.documentElement.animate(
      {
        clipPath: [
          `circle(0 at ${x}px ${y}px)`,
          `circle(${endRadius}px at ${x}px ${y}px)`,
        ],
      },
      {
        duration: 500,
        easing: "ease-in",
        // 指定要附加动画的伪元素
        pseudoElement: "::view-transition-new(root)",
      },
    );
  });
}
```

该动画还需要以下 CSS，以关闭默认的 CSS 动画并防止新旧视图状态以任何方式混合（新状态从旧状态上方“擦除”，而不是过渡）：

```css
::view-transition-image-pair(root) {
  isolation: auto;
}

::view-transition-old(root),
::view-transition-new(root) {
  animation: none;
  mix-blend-mode: normal;
  display: block;
}
```

规范
--

| Specification |
| --- |
| CSS View Transitions Module Level 1 # viewtransition |

浏览器兼容性
------

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

参见
--

* 使用 View Transitions API 实现平滑、简单的过渡


HTMLAudioElement - Web API 接口参考

HTMLAudioElement
================

**`HTMLAudioElement`** 接口提供对 `<audio>` 元素的属性访问及一系列操控它的方法，它基于并从 `HTMLMediaElement` 接口继承属性和方法。

构造函数
----

`Audio()`

创建并返回一个新的 `HTMLAudioElement` 对象，如果提供音频文件 URL，则开始加载音频文件。

属性
--

*没有具体的属性；从父类 `HTMLMediaElement` 和 `HTMLElement` 继承属性。*

方法
--

*从父类 `HTMLMediaElement` 和 `HTMLElement` 继承方法，自身不提供方法。*

### 废弃的且仅适用于 Mozilla 的方法

*以下方法是未标准化的，请勿使用.*

`mozCurrentSampleOffset()`
非标准

已弃用

Returns the number of samples form the beginning of the stream that have been written so far into the audio stream created by calling `mozWriteAudio()`.

`mozSetup()`
非标准

已弃用

Sets up the audio stream to allow writing, given the number of audio channels (1 or 2) and the sample rate in kHz.

`mozWriteAudio()`
非标准

已弃用

Writes a batch of audio frames to the stream at the current offset, returning the number of bytes actually written to the stream.

示例
--

### 基本用法

你可以完全使用 JavaScript 的 `Audio()` 构造函数来创建一个 `HTMLAudioElement` ：

```js
var audioElement = new Audio("car\_horn.wav");
```

然后你可以在这个元素上调用 `play()` 方法

```js
audioElement.play();
```

**备注：** 一个常见的需求是在页面加载后马上去播放音频，现代浏览器的默认自动播放策略会阻止这一行为，参见 firefox 和 chrome 寻找最佳实践和解决方案。

一些经常被使用的属性，包括 `src`、`currentTime`、`duration`、`paused`、`muted` 和 `volume`。以下这段代码赋值音频文件的播放时长给一个变量：

```js
var audioElement = new Audio("car\_horn.wav");
audioElement.addEventListener("loadeddata", () => {
  let duration = audioElement.duration;
  // duration 变量现在存放音频的播放时长（单位秒）
});
```

事件
--

*从父类 `HTMLMediaElement` 和祖先 `HTMLElement` 继承方法。使用* `addEventListener()` *监听事件或者赋值一个事件监听器给这个接口的* `oneventname` 属性。

规范
--

| Specification |
| --- |
| HTML Standard # htmlaudioelement |

浏览器兼容性
------

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

参见
--

* Web media technologies
* Using audio and video in HTML (en-US)
* HTML element implementing this interface: `<audio>`.


MediaStreamAudioSourceNode - Web API 接口参考

MediaStreamAudioSourceNode
==========================

`MediaStreamAudioSourceNode` 接口代表一个音频接口，是WebRTC (en-US) `MediaStream` (比如一个摄像头或者麦克风) 的一部分。是个表现为音频源的`AudioNode`。

`MediaElementSourceNode 没有输入，并且只有一个输出。创建之后使用` `AudioContext.createMediaStreamSource`方法。输出通道的数量和`AudioMediaStreamTrack`的通道数量相同。如果没有有效的媒体流，输出通道就变成一个静音的通道。

|  |  |
| --- | --- |
| Number of inputs | `0` |
| Number of outputs | `1` |
| Channel count |
 由`AudioMediaStreamTrack`定义，传递给
 `AudioContext.createMediaStreamSource`
 ，并由此创建。
  |

构造器
---

`MediaStreamAudioSourceNode.MediaStreamAudioSourceNode()`

创建一个新的`MediaStreamAudioSourceNode`实例。

属性
--

*从 `AudioNode` 上继承。*

方法
--

*从 `AudioNode` 上继承。*

示例
--

参见 `AudioContext.createMediaStreamSource()` 以获取有关该对象用法的示例代码。

规范
--

| Specification |
| --- |
| Web Audio API # MediaStreamAudioSourceNode |

浏览器兼容性
------

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

参见
--

* 使用 Web Audio API


IDBKeyRange - Web API 接口参考

IDBKeyRange
===========

IndexedDB API 的 **`IDBKeyRange`** 接口表示一些数据类型上的键的连续间隔。可以使用一个键或某个范围的键从`IDBObjectStore` 和`IDBIndex` 对象中检索记录。你也可以指定键的上界和下界来限制范围。例如，你可以遍历值范围 a - z 中的键的所有值。

键范围可以是单个值，也可以是具有上界、下界或端点的范围。如果键范围同时有上界或下界，那么它是有界的，否则是无界的。有界键范围可以是开放的（不包含端点）或闭合的（包含了端点）。要检索一定范围内的所有键值，可以使用以下的代码结构：

| Range | Code |
| --- | --- |
| All keys ≤ **x** | `IDBKeyRange.upperBound` (en-US)`(x)` |
| All keys < **x** | `IDBKeyRange.upperBound` (en-US)`(x, true)` |
| All keys ≥ **y** | `IDBKeyRange.lowerBound``(y)` |
| All keys > **y** | `IDBKeyRange.lowerBound``(y, true)` |
| All keys ≥ **x** && ≤ **y** | `IDBKeyRange.bound` (en-US)`(x, y)` |
| All keys > **x** &&< **y** | `IDBKeyRange.bound` (en-US)`(x, y, true, true)` |
| All keys > **x** && ≤ **y** | `IDBKeyRange.bound` (en-US)`(x, y, true, false)` |
| All keys ≥ **x** &&< **y** | `IDBKeyRange.bound` (en-US)`(x, y, false, true)` |
| The key = **z** | `IDBKeyRange.only` (en-US)`(z)` |

如果以下条件为 true，则键包含在键范围中：

* 键范围的下界值为以下值或符合以下条件之一时：
    + `undefined`
    + 低于正在被鉴定的键值
    + 等于正在被鉴定的键值，且键范围的 `lowerOpen` 属性为 `false`.
* 键范围的上界值为以下值或符合以下条件之一时：
    + `undefined`
    + 高于正在被鉴定的键值
    + 等于正在被鉴定的键值，且键范围的 `upperOpen` 属性为 `false`.

**备注：** 此特性在 Web Worker 中可用

Properties
----------

`IDBKeyRange.lower` (en-US) 只读

键范围的下界

`IDBKeyRange.upper` (en-US) 只读

键范围的上界

`IDBKeyRange.lowerOpen` (en-US) 只读

如果下界值包含在键范围内，则返回 false。

`IDBKeyRange.upperOpen` (en-US) 只读

如果上界值包含在键范围内，则返回 false。

Methods
-------

### Static methods

`IDBKeyRange.bound()` (en-US)

指定上界和下界来创建一个新的键范围

`IDBKeyRange.only()` (en-US)

指定单个键值来创建一个新的键范围

`IDBKeyRange.lowerBound()`

指定结果集的下界来创建一个新的键范围

`IDBKeyRange.upperBound()` (en-US)

指定结果集的上界来创建一个新的键范围

### Instance methods

`IDBKeyRange.includes()` (en-US)

返回一个布尔值来表示指定的键是否在键范围内。

Examples
--------

以下示例用以说明该如果使用键范围。在此我们将 `keyRangeValue` 声明为 A ～ F 之间的范围。我们打开一个事务 (使用 `IDBTransaction`) 和一个对象存储，并用 `IDBObjectStore.openCursor`打开一个游标，其中`keyRangeValue`是一个可选的键范围值，指定之后游标将只检索键在该范围内的记录。这里的键范围包括了“A”和“F”，因为我们还没声明键范围为开放边界。如果我们使用 `IDBKeyRange.bound("A", "F", true, true);`，那么这个键范围将不包括“A”和“F”，只包含它们之间的值。

**备注：** For a more complete example allowing you to experiment with key range, have a look at our IDBKeyRange-example repo (view the example live too).

```js
function displayData() {
  var keyRangeValue = IDBKeyRange.bound("A", "F");

  var transaction = db.transaction(["fThings"], "readonly");
  var objectStore = transaction.objectStore("fThings");

  objectStore.openCursor(keyRangeValue).onsuccess = function (event) {
    var cursor = event.target.result;
    if (cursor) {
      var listItem = document.createElement("li");
      listItem.innerHTML =
        "<strong>" + cursor.value.fThing + "</strong>, " + cursor.value.fRating;
      list.appendChild(listItem);

      cursor.continue();
    } else {
      console.log("Entries all displayed.");
    }
  };
}
```

Specifications
--------------

| Specification |
| --- |
| Indexed Database API 3.0 # keyrange |

Browser compatibility
---------------------

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

See also
--------

* Using IndexedDB
* Starting transactions: `IDBDatabase`
* Using transactions: `IDBTransaction`
* Setting a range of keys: `IDBKeyRange`
* Retrieving and making changes to your data: `IDBObjectStore`
* Using cursors: `IDBCursor`
* Reference example: To-do Notifications (view example live.)


Client - Web API 接口参考

Client
======

`Client` 接口表示一个可执行的上下文，如 `Worker` 或 `SharedWorker`。`Window` 客户端由更具体的 `WindowClient` (en-US) 表示。你可以从 `Clients.matchAll()` 和 `Clients.get()` 等方法获取 `Client`/`WindowClient` 对象。

实例方法
----

`Client.postMessage()`

向客户端发送一条消息。

实例属性
----

`Client.id` 只读

一个字符串，表示客户端的通用唯一标识。

`Client.type` (en-US) 只读

表示客户端类型的字符串。可能是 `"window"`、`"worker"` 或 `"sharedworker"`。

`Client.url` (en-US) 只读

表示客户端 URL 的字符串。

规范
--

| Specification |
| --- |
| Service Workers # client-interface |

浏览器兼容性
------

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

参见
--

* 使用 Service Worker (en-US)
* 是否支持 ServiceWorker？
* Promise