使用 Gamepad API - Web API 接口参考

使用 Gamepad API
==============

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

HTML5 为丰富的交互式游戏开发引入了许多必要的组件。像 `<canvas>` 、WebGL、 `<audio>` 和 `<video>` 这样的技术，随着 JavaScript 的逐渐成熟，许多以前需要 native code 来实现的功能现在都可以实现了。Gamepad(手柄) API 是开发人员和设计者识别和使用游戏控制板和其他游戏控制器的一种方法。

Gamepad API 引入新的事件在 `Window` 对象中，来读取手柄和控制器（以下称“控制器”）的状态。除此之外，API 还添加了一个 `Gamepad` 对象，你可以用它来查询已连接控制器的状态；还有一个 `navigator.getGamepads()` 方法，你可以使用它来获取页面已知的控制器列表。

连接控制器
-----

当一个新的手柄连接到计算机时，焦点页面 (当前页面) 首先接收一个 `gamepadconnected` 事件。如果在加载页面时已经连接了手柄，则会在用户按下某个按钮或移动坐标方向 (axes) 时触发焦点页面的 `gamepadconnected` 事件。

**备注：** 在 Firefox 中，控制器只会暴露给与用户产生交互的可见页面。这有助于防止控制器被用于获取用户的指纹。一旦有一个手柄与页面产生交互，那么其他连接的控制器将自动对页面可见。

你可以这样使用 `gamepadconnected` ：

```js
window.addEventListener("gamepadconnected", function (e) {
  console.log(
    "控制器已连接于 %d 位：%s. %d 个按钮，%d 个坐标方向。",
    e.gamepad.index,
    e.gamepad.id,
    e.gamepad.buttons.length,
    e.gamepad.axes.length,
  );
});
```

每个控制器都有一个与之关联的唯一 ID，其在事件的 `gamepad` 属性上可用。

断开控制器连接
-------

当控制器断开连接时，如果页面以前接收过该手柄的数据 (例如 `gamepadconnected`)，那么第二个事件 `gamepaddisconnected` (en-US) 将会分配至焦点页面：

```js
window.addEventListener("gamepaddisconnected", function (e) {
  console.log("控制器已从 %d 位断开：%s", e.gamepad.index, e.gamepad.id);
});
```

即使使用相同类型的多个控制器，控制器的 `index` (en-US) 属性都会是唯一的，每一个设备都有一个。`index` 属性还可充当 `Navigator.getGamepads()` 返回 `Array` 的索引。

```js
var gamepads = {};

function gamepadHandler(event, connecting) {
  var gamepad = event.gamepad;
  // 注：
  // gamepad === navigator.getGamepads()[gamepad.index]

  if (connecting) {
    gamepads[gamepad.index] = gamepad;
  } else {
    delete gamepads[gamepad.index];
  }
}

window.addEventListener(
  "gamepadconnected",
  function (e) {
    gamepadHandler(e, true);
  },
  false,
);
window.addEventListener(
  "gamepaddisconnected",
  function (e) {
    gamepadHandler(e, false);
  },
  false,
);
```

上面的示例同时演示了在事件完成后如何保存 `gamepad` 属性，并在之后使用其查询设备状态。

查询 Gamepad 对象
-------------

正如你看到的，上面讨论的 **gamepad** 事件，包括事件对象上的 `gamepad` 属性，会返回一个 `Gamepad` 对象。因为可能同时连接不止一个控制器，所以我们可以使用它来确定是哪个控制器 (或者说 ID) 触发了事件。我们可以使用 `Gamepad` 对象做很多事，比如保留对象的引用并用其查询，以找出哪些按钮和摇杆在什么时候被按下了。相较于在下次触发，现在立即就可以获取控制器的状态对于游戏或其他交互式网页来说是一般是可取的。

开发者执行此类查询时往往涉及将 `Gamepad` 对象和一个动画循环 (例如 `requestAnimationFrame`) 结合在一起，希望根据控制器的状态来对决定当前框架的行为。

`Navigator.getGamepads()` 方法返回当前对网页可见的所有设备的数组，`Gamepad` 对象 (初始值始终为 `null`，所以当没有控制器连接的时候将会返回 `null` ) 也一样可以用来获取的控制器信息。例如下面将会重写开头的第一个例子：

```js
window.addEventListener("gamepadconnected", function (e) {
  var gp = navigator.getGamepads()[e.gamepad.index];
  console.log(
    "控制器已连接于 %d 位：%s. %d 个按钮，%d 个坐标方向。",
    gp.index,
    gp.id,
    gp.buttons.length,
    gp.axes.length,
  );
});
```

以下是 `Gamepad` 对象的属性说明：

* `id`: 包含一些关于控制器信息的字符串。它的格式没有特定规范，但是在 Firefox 中它将会含有三部分信息并以连接线连接 (`-`)：包含控制器的 USB 供应商、产品 ID 的两个 4 位十六进制字符串以及驱动程序提供的控制器的名称。此信息旨在允许你为设备上的控件查找适当的映射，并向用户显示有用的反馈。
* `index`: 每个已连接手柄唯一的索引数字，可以用来区分多个控制器。请注意，断开目前的设备并连接一个新的设备可能会使用之前的索引值。
* `mapping`: 一个用来指示浏览器是否已将设备上的控件重新映射到已知布局的字符串。目前只有一个受支持的已知布局 - standard gamepad(标准控制器)。如果浏览器能够将设备上的控件映射为该布局，`mapping` 属性将会为字符串 `standard`。
* `connected`: 一个用来指示控制器是否连接到系统的布尔值。如果已连接则为 `True`；反之则为 `False`。
* `buttons`: 一个表示设备上按钮的 `GamepadButton` 数组对象。每个 `GamepadButton` 都含有一个 `pressed` 和一个 `value` 属性：
    + `pressed` 属性是一个表示按钮当前是按下 (`true`) 还是没按下 (`false`) 的布尔值。
    + `value` 属性是一个表示已触发模拟按钮 (例如目前很多控制器的线性/段式扳机键) 的值的浮点值。值的范围被规范为 0.0 到 1.0。0.0 表示没被按下的按钮，1.0 表示被完全按下的按钮。
* `axes`: 一个表示设备上坐标输入控件 (例如控制器摇杆) 的数组对象。数组中的每个值都是介于 -1.0 到 1.0 的浮点值，来表示坐标方向的最低 (-1.0) 和最大 (1.0) 值。
* `timestamp`: 它将返回一个 `DOMHighResTimeStamp` ，该值表示上次更新此控制器数据的时间，以便开发者确定 `axes` 和 `button` 数据是否已从硬件更新。该值必须相对于 `PerformanceTiming` 接口的 `navigationStart` 对象。值是单调递增的，这意味着可以通过对比大小来确定数据更新的先后顺序，因为新的值始终比旧的值大。请注意 Firefox 当前不支持该属性。

**备注：** 出于安全原因，Gamepad 对象在 `gamepadconnected` 事件上可用而在 `Window` 对象上不可用。一旦我们得到了对它的引用，我们就可以获取其属性以了解有关控制器当前状态的信息。在后台，此对象将会在控制器状态更改时更新。

### 使用按键信息

让我们看一个简单的示例：显示一个控制器的连接信息 (忽略后续连接的控制器) ，并让你使用控制器右侧的四个操作按钮移动屏幕上一个球。你可以 查看在线演示，并可在 Github 上找到源代码。

我们首先声明一些变量：`gamepadInfo` 用于写入连接信息的段落；`ball` 是我们希望控制移动的球；`start` 作为 `requestAnimation Frame` ID 的初始变量； `a` 和 `b` 变量作为球位置动量，并且变量会被用于 `requestAnimationFrame()` 和 `cancelAnimationFrame()` 。（？）

```js
var gamepadInfo = document.getElementById("gamepad-info");
var ball = document.getElementById("ball");
var start;
var a = 0;
var b = 0;
```

接下来我们使用 `gamepadconnected` 事件来检查控制器是否连接。当有一个控制连接时，我们就使用 `Navigator.getGamepads()``[0]` 来抓取，输出控制器信息到我们“控制器信息”的 `div` 里，并开始 `gameLoop()` 函数来启动球的运动进程。

```js
window.addEventListener("gamepadconnected", function (e) {
  var gp = navigator.getGamepads()[e.gamepad.index];
  gamepadInfo.innerHTML =
    "控制器已连接于 " +
    gp.index +
    " 位：" +
    gp.id +
    "。它有 " +
    gp.buttons.length +
    " 个按钮和 " +
    gp.axes.length +
    " 个坐标方向。";

  gameLoop();
});
```

现在我们再使用 `gamepaddisconnected` (en-US) 事件来检查如果控制器断开的情况。如果断开了，我们会停止 `requestAnimationFrame()` 循环 (见下方) 并重置控制器信息到原来的样子。

```js
window.addEventListener("gamepaddisconnected", function (e) {
  gamepadInfo.innerHTML = "正在等待控制器。";

  cancelRequestAnimationFrame(start);
});
```

Chrome 在这里有些区别。它没有在变量内不断的更新存储控制器的最后状态，而存储只是当时的一个快照，所以你要在 Chrome 中做到同样的事情的话，就需要不断地轮询，然后在可用的时候只能在代码中使用 `Gamepad` 对象来达到目的。我们下面用 `Window.setInterval()`实现了; 一旦对象可用，控制器信息就会被输出，游戏循环就会开始，可以使用 `Window.clearInterval()` 清除定时循环。请注意在较旧版本的 Chrome 中实现 `Navigator.getGamepads()` 需要加上 `webkit` 前缀。我们尝试对两种前缀版本都进行监测和处理，以向后兼容。

```js
var interval;

if (!("ongamepadconnected" in window)) {
  // 没有控制器事件可用，则开始轮询。
  interval = setInterval(pollGamepads, 500);
}

function pollGamepads() {
  var gamepads = navigator.getGamepads
    ? navigator.getGamepads()
    : navigator.webkitGetGamepads
      ? navigator.webkitGetGamepads
      : [];
  for (var i = 0; i < gamepads.length; i++) {
    var gp = gamepads[i];
    if (gp) {
      gamepadInfo.innerHTML =
        "控制器已连接于 " +
        gp.index +
        " 位：" +
        gp.id +
        "。它有 " +
        gp.buttons.length +
        " 个按钮和 " +
        gp.axes.length +
        " 个坐标方向。";
      gameLoop();
      clearInterval(interval);
    }
  }
}
```

现在看主要的游戏循环。在每次我们所需的四个按钮被按下的时候进行处理。如果被按下了我就会适当地更新动量变量 `a` 和 `b` 的值，然后分别用 `a` 和 `b` 的值更新球的 `left` 和 `top` 属性。这样就可以在屏幕上移动数的位置了。在当前版本的 Chrome 中 (版本 34) button 的值是存储为数组的两个值，而不是 `GamepadButton` 对象。此问题已于开发者版本修复了。

当这些处理好之后，我们使用我们的 `requestAnimationFrame()` 来请求下一个动画帧，然后运行 `gameLoop()` 再继续执行。

```js
function buttonPressed(b) {
  if (typeof b == "object") {
    return b.pressed;
  }
  return b == 1.0;
}

function gameLoop() {
  var gamepads = navigator.getGamepads
    ? navigator.getGamepads()
    : navigator.webkitGetGamepads
      ? navigator.webkitGetGamepads
      : [];
  if (!gamepads) {
    return;
  }

  var gp = gamepads[0];
  if (buttonPressed(gp.buttons[0])) {
    b--;
  } else if (buttonPressed(gp.buttons[2])) {
    b++;
  }
  if (buttonPressed(gp.buttons[1])) {
    a++;
  } else if (buttonPressed(gp.buttons[3])) {
    a--;
  }

  ball.style.left = a \* 2 + "px";
  ball.style.top = b \* 2 + "px";

  start = requestAnimationFrame(gameLoop);
}
```

完整的示例：显示控制器状态
-------------

这个示例展示了怎样使用 `Gamepad` 对象，还有 `gamepadconnected` 和 `gamepaddisconnected` (en-US) 事件显示所有已连接到系统的控制器的状态。你可以查看在线演示并且可在 Github 上看到完整的源代码。

```js
var haveEvents = "ongamepadconnected" in window;
var controllers = {};

function connecthandler(e) {
  addgamepad(e.gamepad);
}

function addgamepad(gamepad) {
  controllers[gamepad.index] = gamepad;

  var d = document.createElement("div");
  d.setAttribute("id", "controller" + gamepad.index);

  var t = document.createElement("h1");
  t.appendChild(document.createTextNode("控制器：" + gamepad.id));
  d.appendChild(t);

  var b = document.createElement("div");
  b.className = "buttons";
  for (var i = 0; i < gamepad.buttons.length; i++) {
    var e = document.createElement("span");
    e.className = "button";
    //e.id = "b" + i;
    e.innerHTML = i;
    b.appendChild(e);
  }

  d.appendChild(b);

  var a = document.createElement("div");
  a.className = "axes";

  for (var i = 0; i < gamepad.axes.length; i++) {
    var p = document.createElement("progress");
    p.className = "axis";
    //p.id = "a" + i;
    p.setAttribute("max", "2");
    p.setAttribute("value", "1");
    p.innerHTML = i;
    a.appendChild(p);
  }

  d.appendChild(a);

  // 见 https://github.com/luser/gamepadtest/blob/master/index.html
  var start = document.getElementById("start");
  if (start) {
    start.style.display = "none";
  }

  document.body.appendChild(d);
  requestAnimationFrame(updateStatus);
}

function disconnecthandler(e) {
  removegamepad(e.gamepad);
}

function removegamepad(gamepad) {
  var d = document.getElementById("controller" + gamepad.index);
  document.body.removeChild(d);
  delete controllers[gamepad.index];
}

function updateStatus() {
  if (!haveEvents) {
    scangamepads();
  }

  var i = 0;
  var j;

  for (j in controllers) {
    var controller = controllers[j];
    var d = document.getElementById("controller" + j);
    var buttons = d.getElementsByClassName("button");

    for (i = 0; i < controller.buttons.length; i++) {
      var b = buttons[i];
      var val = controller.buttons[i];
      var pressed = val == 1.0;
      if (typeof val == "object") {
        pressed = val.pressed;
        val = val.value;
      }

      var pct = Math.round(val \* 100) + "%";
      b.style.backgroundSize = pct + " " + pct;

      if (pressed) {
        b.className = "button pressed";
      } else {
        b.className = "button";
      }
    }

    var axes = d.getElementsByClassName("axis");
    for (i = 0; i < controller.axes.length; i++) {
      var a = axes[i];
      a.innerHTML = i + ": " + controller.axes[i].toFixed(4);
      a.setAttribute("value", controller.axes[i] + 1);
    }
  }

  requestAnimationFrame(updateStatus);
}

function scangamepads() {
  var gamepads = navigator.getGamepads
    ? navigator.getGamepads()
    : navigator.webkitGetGamepads
      ? navigator.webkitGetGamepads()
      : [];
  for (var i = 0; i < gamepads.length; i++) {
    if (gamepads[i]) {
      if (gamepads[i].index in controllers) {
        controllers[gamepads[i].index] = gamepads[i];
      } else {
        addgamepad(gamepads[i]);
      }
    }
  }
}

window.addEventListener("gamepadconnected", connecthandler);
window.addEventListener("gamepaddisconnected", disconnecthandler);

if (!haveEvents) {
  setInterval(scangamepads, 500);
}
```

规范
--

| Specification |
| --- |
| Gamepad # gamepad-interface |
| Gamepad Extensions # partial-gamepad-interface |

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

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


CSSValueList.length - Web API 接口参考

CSSValueList.length
===================

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

`CSSValueList` 接口的只读属性 **`length`** 表示列表中的 `CSSValue` 数量。有效的索引区间为 `0` 到 `length-1`。

语法
--
```

var length = cssValueList.length;
```

### 值

一个 `unsigned long` 数值，表示此列表中 `CSSValue` 的个数。

规范
--

该特性最初在 DOM Style Level 2 中定义，但从那时起已从标准化工作中移除。

它已被现代、不兼容的 CSS 类型对象模型 API (en-US) 取代，该 API 已被标准化。

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

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


Determining the dimensions of elements - Web API 接口参考

Determining the dimensions of elements
======================================

当想要确认元素的宽高时有几种属性可以选择，但是我们很难确认使用哪个属性才是最适合的。本文将帮助你做出正确的选择。

元素占用了多少空间？
----------

如果你需要知道元素总共占用了多少空间，包括可视内容、滚动条（如果有的话）、内边距和边框的宽度，你会使用 `offsetWidth` 和 offsetHeight 属性，大多数情况下，当元素没有什么形状上的变化时，他们与 getBoundingClientRect()的宽高一致。但是如果发生变化，offsetWidth 和 offsetHeight 将返回元素的布局宽高，而 getBoundingClientRect() 将返回实际渲染的宽高。例如：如果元素的宽 width:100px，变化 transform:scale(0.5)，此时 getBoundingClientRect() 将返回宽 50，而 offsetWidth 将返回宽 100.

![Image:Dimensions-offset.png](/zh-CN/docs/Web/API/CSS_Object_Model/Determining_the_dimensions_of_elements/dimensions-offset.png)

显示内容尺寸是多少？
----------

如果你需要知道展示区域内容占用了多少空间，包括内边距但是不包括边框、外边距或者滚动条，你会使用clientWidth和clientHeight属性：

![Image:Dimensions-client.png](/zh-CN/docs/Web/API/CSS_Object_Model/Determining_the_dimensions_of_elements/dimensions-client.png)

内容有多大？
------

如果你想要知道内容区域的实际大小，而不局限于可见区域的话，你会使用 `scrollWidth`和scrollHeight属性。即使使用了滚动条仅有部分内容可见，这两个属性仍会返回元素的完整内容宽高

例如，一个 300x300 像素 的滚动盒子里放置了一个 600x400 像素的元素，scrollWidth 将会返回 600，scrooHeight 返回 400.

规范
--

http://www.w3.org/TR/cssom-view/

参考文献
----

MSDN Measuring Element Dimension and Location


关于使用动态样式的信息 - Web API 接口参考

关于使用动态样式的信息
===========

CSS 对象模型（CSSOM），是 DOM 的一部分，通过暴露一些接口，允许操作很多与 CSS 相关的信息。最初定义在 *DOM Level 2 Style* 提议中，现在，这些接口形成了一个规范，*CSS 对象模型（CSSOM）*，旨在取代它。

在很多情况下，如果可能的话，通过 `className` 属性来动态操作元素类名确实是最好的方式，因为所有的样式钩子的最终外观都可以在一个样式表中控制。这样写出的 JavaScript 代码也会变得更清晰，因为它不专注与样式相关的细节，而是专注于所创作或者操作的每一部分的整体语义，将精细的样式细节留给样式表。然而实际上也有以一些获取或者操作样式规则有用的情况（无论是对于正样式包还是的那个元素），将在下面进一步详细描述。同样应该注意，同操作单独元素的样式一样，当说到操作样式表的时候，并不是真的操作实际的物理文档，而仅仅是文档的内部表示。

基本样式对象公开了 `Stylesheet` 和 `CSSStylesheet` 接口。这些接口包括 `insertRule`、`selectorText` 以及 `parentStyleSheet` 等成员，用于获取和操作组成 CSS 样式表的各个规则。

要从 `document` 中获取 `style` 对象，可以使用 `document.styleSheets` 属性，并使用索引来获取某个对象（例如， `document.styleSheets[0]` 是该文档中的第一个样式表）。

通过 CSSOM 修改样式表
--------------

```html
<html>
  <head>
    <title>Modifying a stylesheet rule with CSSOM</title>
    <style type="text/css">
 body {
 background-color: red;
 }
 </style>
    <script type="text/javascript">
 var stylesheet = document.styleSheets[1];
 stylesheet.cssRules[0].style.backgroundColor = "blue";
 </script>
  </head>
  <body>
    The stylesheet declaration for the body's background color is modified via
    JavaScript.
  </body>
</html>
```

DOM CSS Properties List (en-US) 中给出了 DOM 中 style 属性的可用属性列表。

若要使用 CSS 语法修改文档的样式，可以插入样式规则，或者插入`<style>` 标签，并将其 `innerHTML` 属性设置为期望的 CSS。

修改元素样式
------

元素的 `style` 属性（见下面的 DOM 样式对象部分）也可以用于获取和设置元素的样式。然而，该属性只能返回通过内敛方式设置的样式属性（例如 `<td style="background-color: lightblue">` 返回 "`background-color:lightblue`"，或者直接针对哪个元素使用 `element.style.propertyName`, 即使样式表中还有该元素上的其他样式）。

此外，当你在元素上设置某个属性的时候，你会覆盖并擦除掉别处为该元素的这个属性设置的值。以设置 border 属性为例，将覆盖掉在 <head> 部分或者外部样式表设置的该元素的 border 属性。然而这并不会影响元素的其他属性，例如 padding、margin 或 font 等。

要修改特定元素的样式，可以将以下示例修改为你想要的样式。

```html
<html>
  <head>
    <title>simple style example</title>

    <script type="text/javascript">
 function alterStyle(elem) {
 elem.style.background = "green";
 }

 function resetStyle(elemId) {
 elem = document.getElementById(elemId);
 elem.style.background = "white";
 }
 </script>

    <style type="text/css">
 #p1 {
 border: solid blue 2px;
 }
 </style>
  </head>

  <body>
    <!-- passes a reference to the element's object as parameter 'this'. -->
    <p id="p1" onclick="alterStyle(this);">
      Click here to change background color.
    </p>

    <!-- passes the 'p1' id of another element's style to modify. -->
    <button onclick="resetStyle('p1');">Reset background color</button>
  </body>
</html>
```

`document.defaultView` 对象的 `getComputedStyle()` 返回某个元素的所有经过计算的样式。查看Example 6: getComputedStyle 示例章节了解更多使用该方法的信息。.

DOM 样式对象
--------

`style` 对象表示了一个单独的样式声明。不像`document.styleSheets` 集合中每个单独的样式规则，样式规则是通过 `document` 对象或者应用改样式的元素来访问的。它表示特定元素的内联样式。

比这两个属性更重要的是使用 `style` 对象来给某个元素设置单独的样式属性。

```html
<!doctype html>
<html>
  <head>
    <title>style Property Example</title>
    <link rel="StyleSheet" href="example.css" type="text/css" />
    <script type="text/javascript">
 function stilo() {
 document.getElementById("d").style.color = "orange";
 }
 function resetStyle() {
 document.getElementById("d").style.color = "black";
 }
 </script>
  </head>

  <body>
    <div id="d" class="thunder">Thunder</div>
    <button onclick="stilo()">Click here to change text color</button>
    <button onclick="resetStyle()">Reset text color</button>
  </body>
</html>
```

style 的 media 和 type 给不给出都可以。

### 使用 `setAttribute` 方法

注意，你也可以通过获得元素的引用，然后使用它的 `setAttribute` 方法，指定 CSS 属性和值，来改变该元素的样式。

```js
var el = document.getElementById("some-element");
el.setAttribute("style", "background-color:darkblue;");
```

但请注意，`setAttribute` 会移除该元素样式对象中已经定义的其他样式属性。如果上面的 `some-element` 有一个行内样式属性：`style="font-size: 18px"`，其值将会因为使用了 `setAttribute` 方法而被移除。


ImageData() - Web API 接口参考

ImageData()
===========

**`ImageData()`** 构造函数返回一个新的实例化的 `ImageData` 对象，此对象由给定的类型化数组和指定的宽度与高度组成。

这个构造器是创建像这种对象首选的方式。

语法
--
```

new ImageData(array, width, height);
new ImageData(width, height);
```

### 参数

`array`

包含图像隐藏像素的 `Uint8ClampedArray` 数组。如果数组没有给定，指定大小的黑色矩形图像将会被创建。

`width`

无符号长整型（unsigned long）数值，描述图像的宽度。

`height`

 无符号长整型（unsigned long）数值，描述图像的高度。
 如果已给定数组，这个值是可选的：它将通过它的大小和给定的宽度进行推断。

示例
--

```js
var imageData = new ImageData(100, 100); // Creates a 100x100 black rectangle
// ImageData { width: 100, height: 100, data: Uint8ClampedArray[40000] }
```

规范
--

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

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

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

参见
--

* `CanvasRenderingContext2D.createImageData()`, the creator method that can be used outside workers.


ImageData.height - Web API 接口参考

ImageData.height
================

只读的 **`ImageData.height`** 属性，返回在图像数据对象中的行的数量。

语法
--
```

imagedata.height
```

示例
--

```js
var imagedata = new ImageData(100, 100);
imagedata.height; // 100
```

规范
--

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

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

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

参见
--

* `ImageData.width`


ImageData.width - Web API 接口参考

ImageData.width
===============

只读的 **`ImageData.width`** 属性，返回在图像数据对象中每一行像素的数量。

语法
--
```

imagedata.width
```

示例
--

```js
var imagedata = new ImageData(100, 100);
imagedata.width; // 100
```

规范
--

| Specification |
| --- |
| HTML Standard # dom-imagedata-width-dev |

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

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

参见
--

* `ImageData.height`


ImageData.data - Web API 接口参考

ImageData.data
==============

只读的 **`ImageData.data`** 属性，返回 `Uint8ClampedArray` ，描述一个一维数组，包含以 RGBA 顺序的数据，数据使用 `0` 至 `255`（包含）的整数表示。

语法
--
```

imagedata.data
```

示例
--

```js
var imagedata = new ImageData(100, 100);
imagedata.data; // Uint8ClampedArray[40000]
```

规范
--

| Specification |
| --- |
| HTML Standard # dom-imagedata-data-dev |

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

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

参见
--

* `ImageData.height`
* `ImageData.width`


Event.composedPath() - Web API 接口参考

Event.composedPath()
====================

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

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

* Learn more
* See full compatibility
* Report feedback
**`composedPath()`** 是 `Event` 接口的一个方法，当对象数组调用该侦听器时返回事件路径。如果影子根节点被创建并且`ShadowRoot.mode`是关闭的，那么该路径不包括影子树中的节点。

语法
--
```

var composed = Event.composedPath();
```

### 参数

无。

### 返回值

一个 `EventTarget`对象数组，表示将在其上调用事件侦听器的对象。

示例
--

在我们的 composed-composed-path 例子中，我们定义了两个自定义元素，`<open-shadow>` 和 `<closed-shadow>，`两 个全都调用了它们文本属性的内容然后作为`<p>` 元素的文本内容将它们插入到元素的影子 DOM 中。两者之间唯一的区别是它们影子的根结点是在它们的模式被分别设置成`open` 和 `closed` 的情况下连接的。

第一个定义就像这样，比如：

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

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

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

然后我们在我们的页面中插入其中一个元素：

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

然后在 `<html>` 元素中插入一个鼠标点击事件：

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

当你先后点击 `<open-shadow>` 和 `<closed-shadow>` 这两个元素，你将会注意到两件事情。第一， `composed` 这个属性返回值为 `true` 因为 `click` 事件总能够在影子边界中传播。第二，你将注意到两个元素中`composedPath` 的值的不同。 `<open-shadow>` 元素的组成路径是这个：

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

尽管 `<closed-shadow>` 元素的组成路径是像下面这样：

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

在第二个例子中，事件监听器仅能够传播到 `<closed-shadow>` 元素本身，但是不会到影子边界内的节点。

规范
--

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

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

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


Event.target - Web API 接口参考

Event.target
============

`Event` 接口的 **`target`** 只读属性是对事件分派到的对象的引用。当事件处理器在事件的冒泡或捕获阶段被调用时，它与 `event.currentTarget` 不同。

值
-

与 `EventTarget` 有关。

示例
--

`event.target` 属性可以用来实现**事件委托** (**event delegation**)。

```js
// Make a list
var ul = document.createElement("ul");
document.body.appendChild(ul);

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

function hide(e) {
  // e.target 引用着 <li> 元素
  // 不像 e.currentTarget 引用着其父级的 <ul> 元素。
  e.target.style.visibility = "hidden";
}

// 添加监听事件到列表，当每个 <li> 被点击的时候都会触发。
ul.addEventListener("click", hide, false);
```

规范
--

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

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

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

在 IE6-8 中，事件模型与标准不同。使用非标准的 `element.attachEvent()` 方法绑定事件监听器。在该模型中，事件对象有一个 `srcElement` 属性，等价于`target` 属性。

```js
function hide(e) {
  // 支持 IE6-8
  var target = e.target || e.srcElement;
  target.style.visibility = "hidden";
}
```

参见
--

* Comparison of Event Targets
* `Event.currentTarget`


event.stopPropagation - Web API 接口参考

event.stopPropagation
=====================

`Event` 接口的 **`stopPropagation()`** 方法阻止捕获和冒泡阶段中当前事件的进一步传播。但是，它不能防止任何默认行为的发生；例如，对链接的点击仍会被处理。如果要停止这些行为，请参见 `preventDefault()` 方法，它可以阻止事件触发后默认动作的发生。它也不能阻止附加到相同元素的相同事件类型的其他事件处理器，如果要阻止这些处理器的运行，请参见 `stopImmediatePropagation()` 方法。

语法
--

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

### 参数

None.

### 返回值

None.

示例
--

参见冒泡事件。

规范
--

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

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

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


Event.isTrusted - Web API 接口参考

Event.isTrusted
===============

`Event` 接口的 **`isTrusted`** 属性是一个只读属性，它是一个布尔值（`Boolean` (en-US)）。当事件是由用户行为生成的时候，这个属性的值为 `true` ，而当事件是由脚本创建、修改、通过 `EventTarget.dispatchEvent()` 派发的时候，这个属性的值为 `false` 。

语法
--
```

var eventIsTrusted = event.isTrusted;
```

### 值

`Boolean` (en-US)（布尔值）

示例
--

```js
if (e.isTrusted) {
  /\* Event 事件可信 \*/
} else {
  /\* Event 事件不可信 \*/
}
```

规范
--

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

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

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


event.type - Web API 接口参考

event.type
==========

只读属性 **Event.type** 会返回一个字符串，表示该事件对象的事件类型。

传给 `EventTarget.addEventListener()` 和 `EventTarget.removeEventListener()` 方法的 event 参数的值是忽略大小写的。

要了解所有的事件类型，请查看 Mozilla 事件类型参考.

语法
--
```

event.type
```

示例
--

```html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />

    <title>Event.type Example</title>

    <script>
 var currEvent = null;
 function getEvtType(evt) {
 console.log("//Start------------getEvtType(evt)------------ ");

 currEvent = evt.type;
 console.log(currEvent);

 //document.getElementById("Etype").firstChild.nodeValue = currEvent;
 document.getElementById("Etype").innerHTML = currEvent;

 console.log("//End--------------getEvtType(evt)------------ ");
 }

 //Keyboard events
 document.addEventListener("keypress", getEvtType, false); //[second]

 document.addEventListener("keydown", getEvtType, false); //first
 document.addEventListener("keyup", getEvtType, false); //third

 //Mouse events
 document.addEventListener("click", getEvtType, false); // third

 document.addEventListener("mousedown", getEvtType, false); //first
 document.addEventListener("mouseup", getEvtType, false); //second
 </script>
  </head>

  <body>
    <p>Press any key or click the mouse to get the event type.</p>
    <p>Event type: <span id="Etype" style="color:red">-</span></p>
  </body>
</html>
```

### Result

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

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


event.timeStamp - Web API 接口参考

event.timeStamp
===============

**警告：** 在 Gecko 中，该属性的值不是事件发生时正确的事件戳。查看 https://bugzilla.mozilla.org/show\_bug.cgi?id=238041

### 概述

返回事件发生时的时间戳。

### 语法
```

var number = event.timeStamp;
```

### 例子

```html
<html>
  <head>
    <title>timeStamp example</title>

    <script type="text/javascript">
 function getTime(event) {
 document.getElementById("time").firstChild.nodeValue = event.timeStamp;
 }
 </script>
  </head>

  <body onkeypress="getTime(event)">
    <p>按下任意键获取 onkeypress 事件对象的 timestamp 属性值。</p>
    <p>timeStamp: <span id="time">-</span></p>
  </body>
</html>
```

### 备注

此属性仅适用于事件系统支持该属性的特定事件类型。

### 规范

event.timestamp


Event.currentTarget - Web API 接口参考

Event.currentTarget
===================

`Event` 接口的只读属性 **`currentTarget`** 表示的，标识是当事件沿着 DOM 触发时事件的当前目标。它总是指向事件绑定的元素，而 `Event.target` 则是事件触发的元素。

语法
--
```

var currentEventTarget = event.currentTarget;
```

### Value

`EventTarget`例子
--

当将相同的事件处理程序附加到多个元素时 `event.currentTarget` 就很有用。

```js
function hide(e) {
  e.currentTarget.style.visibility = "hidden";
  console.log(e.currentTarget);
  // 该函数用作事件处理器时：this === e.currentTarget
}

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

for (var i = 0; i < ps.length; i++) {
  // console: 打印被点击的 p 元素
  ps[i].addEventListener("click", hide, false);
}
// console: 打印 body 元素
document.body.addEventListener("click", hide, false);
```

**备注：** `event.currentTarget` 的值*只能*在事件处理过程中被使用。如果你尝试用 `console.log()` 在控制台打印 `event` 对象，你会发现 `currentTarget` 的值是 `null`。如果你想在控制台打印 `currentTarget` 的值，你应该使用 `console.log(event.currentTarget)`，或者也可以在代码中使用 `debugger` 语句来暂停代码的执行从而看到 `event.currentTarget` 的值。

规范
--

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

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

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

参考
--

* Comparison of Event Targets


event.bubbles - Web API 接口参考

event.bubbles
=============

### 概述

返回一个布尔值，表明当前事件是否会向 DOM 树上层元素冒泡。

### 语法
```

var bool = event.bubbles;
```

### 备注

一些特定的事件类型会冒泡。这时，该事件对象的`bubbles`属性为`true`. 你可以检查该属性的值来判断一个事件对象是否冒泡。

### 例子

```js
function goInput(e) {
  // 检查事件对象是否冒泡
  if (!e.bubbles) {
    // 如果不冒泡，则手动传递事件
    passItOn(e);
  }
  // 如果冒泡的话
  doOutput(e);
}
```

### 规范

event.bubbles


Event：preventDefault() 方法 - Web API 接口参考

Event：preventDefault() 方法
=========================

`Event` 接口的 **`preventDefault()`** 方法，告诉用户代理：如果此事件没有被显式处理，它默认的动作也不应该照常执行。

此事件还是继续传播，除非碰到事件监听器调用 `stopPropagation()` 或 `stopImmediatePropagation()`，才停止传播。

如后文所述，对于不可取消的事件（例如通过 `EventTarget.dispatchEvent()` 分派的、没有指定 `cancelable: true` 的事件），调用 **`preventDefault()`** 是没有任何效果的。

### 语法

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

示例
--

### 阻止默认的点击事件执行

选中复选框是点击复选框的默认行为。下面这个例子说明了怎样阻止默认行为的发生：

#### JavaScript

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

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

function checkboxClick(event) {
  let warn = "preventDefault() won't let you check this!<br>";
  document.getElementById("output-box").innerHTML += warn;
  event.preventDefault();
}
```

#### HTML

```html
<p>Please click on the checkbox control.</p>

<form>
  <label for="id-checkbox">Checkbox:</label>
  <input type="checkbox" id="id-checkbox" />
</form>

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

#### 结果

你可以看到如下的行为：

### 在编辑域中阻止按键

下面的这个例子说明了如何使用 `preventDefault()` 在文本编辑域中阻止有效的文本输入。如今，你通常可以使用原生的 HTML 表单验证来代替。

#### HTML

此 HTML 表单用于捕获用户输入。由于我们只对按键输入感兴趣，因此我们禁用 `autocomplete` 功能来防止浏览器使用缓存的值填充输入字段。

```html
<div class="container">
  <p>Please enter your name using lowercase letters only.</p>

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

#### CSS

当用户按下一个有效按键的时候，我们就给这个 warning box 加上一些样式：

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

#### JavaScript

这里是相关的 JavaScript 代码。首先，监听 `keypress` 事件：

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

`checkName()` 方法可以监听按键并且决定是否允许按键的默认行为发生。

```js
function checkName(evt) {
  var charCode = evt.charCode;
  if (charCode != 0) {
    if (charCode < 97 || charCode > 122) {
      evt.preventDefault();
      displayWarning(
        "Please use lowercase letters only." +
          "\n" +
          "charCode: " +
          charCode +
          "\n",
      );
    }
  }
}
```

`displayWarning()` 方法显示了一个问题的通知。这不是一种优雅的方法，但是确实可以达到我们的目的。

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

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

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

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

#### 结果

这里就是代码的执行结果：

备注
--

在事件流的任何阶段调用 `preventDefault()` 都会取消事件，这意味着任何通常被该实现触发并作为结果的默认行为都不会发生。

你可以使用 `Event.cancelable` 来检查该事件是否支持取消。为一个不支持 cancelable 的事件调用 `preventDefault()` 将没有效果。

规范
--

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

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

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


Event.cancelBubble - Web API 接口参考

Event.cancelBubble
==================

**`Event.cancelBubble`** 属性是 `Event.stopPropagation()`的一个曾用名。在从事件处理程序返回之前将其值设置为 true 可阻止事件的传播。

语法
--
```

event.cancelBubble = bool;
let bool = event.cancelBubble;
```

用例
--

```js
ele.onclick = function (e) {
  // 在这儿可以做点儿有趣的事情
  e.cancelBubble = true;
};
```

规范
--

*这个属性的规范并未统一。* 因为他还有其他标准 W3C 版： an old Working Draft of W3C DOM Level 2. 微软版： description of it on MSDN.

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

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

参考
--

* `UIEvent.cancelBubble` (en-US)
* translated by cnvoid


Event.composed - Web API 接口参考

Event.composed
==============

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

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

* Learn more
* See full compatibility
* Report feedback
`Event` 接口的只读属性 **`composed`** 返回一个 `Boolean` 值，用来指示该事件是否可以从 Shadow DOM 传递到一般的 DOM。

**备注：** 此属性以前命名为`scoped`。

语法
--

```js
var composed = Event.composed;
```

### 值

如果返回的 `Boolean` 值为 `true`，表明当事件到达 shadow DOM 的根节点（也就是 shadow DOM 中事件开始传播的第一个节点）时，事件可以从 shadow DOM 传递到一般 DOM。当然，事件要具有可传播性，即该事件的 `bubbles` 属性必须为 `true`。你也可以通过调用 `composedPath()` 来查看事件从 shadow DOM 传播到普通 DOM 的路径。

如果属性值为 `false`，那么事件将不会跨越 shadow DOM 的边界传播。

例子
--

在我们的组合组合路径示例（实时查看）中，我们定义了两个不重要的自定义元素 `<open-shadow>` 和 `<closed-shadow>`，它们都将获取其 `text` 属性的内容并将它们作为元素的文本内容插入到元素的 shadow DOM 中。两者之间的唯一区别是它们的阴影根附加了它们的模式分别设置为 open 和 closed。

第一个定义如下所示：

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

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

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

我们将他们插入我们的页面当中：

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

然后在 `html` 标签上监听 click 事件：

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

当我们点击 `<open-shadow>` 和 `<closed-shadow>` 元素时候我们会注意到：

1. `composed` 属性返回 `true` 因为`click` 事件总是能总是能够跨越`Shadow DOM`的边界传播。
2. 你应该会注意到，两个元素返回`composedPath`的值不同。

`<open-shadow>` 元素的组合路径是：
```

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

而 `<closed-shadow>` 元素的组合路径是：
```

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

第二种情况下，监听器只会捕获到 `<closed-shadow>` 元素本身，而不会去继续捕捉该元素中的节点。

规范
--

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

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

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


event.stopImmediatePropagation - Web API 接口参考

event.stopImmediatePropagation
==============================

`Event` 接口的 **`stopImmediatePropagation()`** 方法阻止监听同一事件的其他事件监听器被调用。

如果多个事件监听器被附加到相同元素的相同事件类型上，当此事件触发时，它们会按其被添加的顺序被调用。如果在其中一个事件监听器中执行 `stopImmediatePropagation()` ，那么剩下的事件监听器都不会被调用。

**备注：** 注意与 `event.stopPropagation()` 之间的区别

语法
--
```

event.stopImmediatePropagation();
```

例子
--
```

<!DOCTYPE html>
<html>
    <head>
        <style>
            p { height: 30px; width: 150px; background-color: #ccf; }
            div {height: 30px; width: 150px; background-color: #cfc; }
        </style>
    </head>
    <body>
        <div>
            <p>paragraph</p>
        </div>
        <script>
            const p = document.querySelector('p')
            p.addEventListener("click", (event) => {
              alert("我是 p 元素上被绑定的第一个监听函数");
            }, false);

            p.addEventListener("click", (event) => {
              alert("我是 p 元素上被绑定的第二个监听函数");
              event.stopImmediatePropagation();
              // 执行 stopImmediatePropagation 方法，阻止 click 事件冒泡，并且阻止 p 元素上绑定的其他 click 事件的事件监听函数的执行。
            }, false);

            p.addEventListener("click",(event) => {
              alert("我是 p 元素上被绑定的第三个监听函数");
              // 该监听函数排在上个函数后面，该函数不会被执行
            }, false);

            document.querySelector("div").addEventListener("click", (event) => {
              alert("我是 div 元素，我是 p 元素的上层元素");
              // p 元素的 click 事件没有向上冒泡，该函数不会被执行
            }, false);
        </script>
    </body>
</html>
```

规范
--

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

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

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


Event() - Web API 接口参考

Event()
=======

**`Event()`** 构造函数，创建一个新的事件对象 `Event`。

语法
--
```

 event = new Event(typeArg, eventInit);
```

### 参数

*typeArg*

是`DOMString` 类型，表示所创建事件的名称。

*eventInit*可选

是 `EventInit` 类型的字典，接受以下字段：

* `"bubbles"`，可选，`Boolean`类型，默认值为 `false`，表示该事件是否冒泡。
* `"cancelable"`，可选，`Boolean`类型，默认值为 `false`，表示该事件能否被取消。
* `"composed"`，可选，`Boolean`类型，默认值为 `false`，指示事件是否会在影子 DOM 根节点之外触发侦听器。

示例
--

```js
// 创建一个支持冒泡且不能被取消的 look 事件

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

// 事件可以在任何元素触发，不仅仅是 document
myDiv.dispatchEvent(ev);
```

规范
--

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

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

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

相关阅读
----

* `Event`


Event.initEvent() - Web API 接口参考

Event.initEvent()
=================

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

**`Event.initEvent()`** 方法可以用来初始化由`Document.createEvent()` 创建的 `event` 实例。

用这种方式初始化事件必须是由 `Document.createEvent()` 方法创建的实例。本方法必须在事件被触发之前调用（用`EventTarget.dispatchEvent()`调用）.事件 一旦被调用，便不再做其他任何事。

**备注：** **不建议再使用此方法（方法已经过时 deprecated）**

可以使用特定的 event 构造器函数，比如 `Event()`. 该页有关于这些的更多信息 Creating and triggering events (en-US) .

语法
--
```

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

`type`

一个 `DOMString` 类型的字段，定义了事件的类型。

`bubbles`

一个 `Boolean` 值，决定是否事件是否应该向上冒泡。一旦设置了这个值，只读属性`Event.bubbles`也会获取相应的值。

`cancelable`

一个 `Boolean` 值，决定该事件的默认动作是否可以被取消。一旦设置了这个值，只读属性 `Event.cancelable` 也会获取相应的值。

范例
--
```

// 创建事件。
var event = document.createEvent('Event');

// 初始化一个点击事件，可以冒泡，无法被取消
event.initEvent('click', true, false);

// 设置事件监听。
elem.addEventListener('click', function (e) {
  // e.target 就是监听事件目标元素
}, false);

// 触发事件监听
elem.dispatchEvent(event);
```

规范
--

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

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

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

另见
--

* The constructor to use instead of this deprecated method: `Event()`. More specific constructors can be used too.


event.defaultPrevented - Web API 接口参考

event.defaultPrevented
======================

概述
--

返回一个布尔值，表明当前事件是否调用了 `event.preventDefault()`方法。

**备注：** 你应该使用该属性来代替以前的非标准的已经被废弃的`getPreventDefault()`方法 (查看Firefox bug 691151).

语法
--

```js
bool = event.defaultPrevented;
```

示例
--

```js
if (e.defaultPrevented) {
  /\* 事件的默认动作已被取消\*/
}
```

规范
--

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

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

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


Comparison of Event Targets - Web API 接口参考

Comparison of Event Targets
===========================

### Event targets

It's easy to get confused about which target to examine when writing an event handler. This article should clarify the use of the target properties.

There are 5 targets to consider:

| Property | Defined in | Purpose |
| --- | --- | --- |
| event.target | DOM Event Interface |
 The DOM element on the lefthand side of the call that triggered this
 event, eg:

```

*element*.dispatchEvent(*event*)
```

 |
| event.currentTarget | DOM Event Interface |
 The
 `EventTarget`
 whose
 `EventListeners`
 are currently being processed. As the event capturing and bubbling
 occurs this value changes.
  |
| event.relatedTarget | DOM MouseEvent Interface | Identifies a secondary target for the event. |
| event.explicitOriginalTarget | Event.webidl |
非标准
 If the event was retargeted for
 some reason other than an anonymous boundary crossing, this will be set
 to the target before the retargeting occurs. For example, mouse events
 are retargeted to their parent node when they happen over text nodes
 ([Firefox bug 185889](https://bugzil.la/185889)), and in that case `.target` will
 show the parent and `.explicitOriginalTarget` will show the
 text node.Unlike `.originalTarget`,
 `.explicitOriginalTarget` will never contain anonymous
 content.
  |
| event.originalTarget | Event.webidl |
非标准
 The original target of the event,
 before any retargetings. See
 Anonymous Content#Event\_Flow\_and\_Targeting
 for details.
  |

### Use of `explicitOriginalTarget` and `originalTarget`

TODO: Only available in a Mozilla-based browser? TODO: Only suitable for extension-developers?

### Examples
```

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

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

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

### Use of `target` and `relatedTarget`

The `relatedTarget` property for the `mouseover` event holds the node that the mouse was previously over. For the `mouseout` event, it holds the node that the mouse moved to.

| Event type | event.target | event.relatedTarget |
| --- | --- | --- |
| `mouseover` | the EventTarget which the pointing device entered | the EventTarget which the pointing device exited |
| `mouseout` | the EventTarget which the pointing device exited | the EventTarget which the pointing device entered |

TODO: Also needs descriptions about `dragenter` and `dragexit` events.

#### Example
```

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


Event.eventPhase - Web API 接口参考

Event.eventPhase
================

表示事件流当前处于哪一个阶段。

语法
--

```js
var phase = event.eventPhase;
```

返回一个代表当前执行阶段的整数值，下面列出了不同的执行阶段事件阶段常量。

常量
--

### 事件阶段常量

### 下面这些值表示了事件流当前执行的阶段

| 常量 | 值 | 描述 |
| --- | --- | --- |
| `Event.NONE` | 0 | 这个时间，没有事件正在被处理 |
| `Event.CAPTURING_PHASE` | 1 | 事件正在被目标元素的祖先对象处理。这个处理过程从`Window`开始，然后`Document`, 然后是`HTMLHtmlElement`, 一直这样，直到目标元素的父元素。通过`EventTarget.addEventListener()` 注册为捕获模式的Event listeners 被调用。 |
| `Event.AT_TARGET` | 2 | 事件对象已经抵达the event's target. 为这个阶段注册的事件监听被调用。如果 `Event.bubbles` 的值为 false，对事件对象的处理在这个阶段后就会结束。 |
| `Event.BUBBLING_PHASE` | 3 | 事件对象逆向向上传播回目标元素的祖先元素，从父亲元素开始，并且最终到达包含元素 `Window`. 这就是冒泡，并且只有`Event.bubbles` 值为 true 的时候才会发生。为这个阶段注册的Event listeners 在这个过程中被触发。 |

更多细节，请看section 3.1, Event dispatch and DOM event flow, DOM 级别 3 的事件说明。

示例
--

### HTML 内容

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

### CSS 内容

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

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

### JavaScript 内容

```js
var clear = false,
  divInfo = null,
  divs = null,
  useCapture = false;
window.onload = function () {
  divInfo = document.getElementById("divInfo");
  divs = document.getElementsByTagName("div");
  chCapture = document.getElementById("chCapture");
  chCapture.onclick = function () {
    RemoveListeners();
    AddListeners();
  };
  Clear();
  AddListeners();
};

function RemoveListeners() {
  for (var i = 0; i < divs.length; i++) {
    var d = divs[i];
    if (d.id != "divInfo") {
      d.removeEventListener("click", OnDivClick, true);
      d.removeEventListener("click", OnDivClick, false);
    }
  }
}

function AddListeners() {
  for (var i = 0; i < divs.length; i++) {
    var d = divs[i];
    if (d.id != "divInfo") {
      d.addEventListener("click", OnDivClick, false);
      if (chCapture.checked) d.addEventListener("click", OnDivClick, true);
      d.onmousemove = function () {
        clear = true;
      };
    }
  }
}

function OnDivClick(e) {
  if (clear) {
    Clear();
    clear = false;
  }
  if (e.eventPhase == 2) e.currentTarget.style.backgroundColor = "red";
  var level =
    e.eventPhase == 0
      ? "none"
      : e.eventPhase == 1
        ? "capturing"
        : e.eventPhase == 2
          ? "target"
          : e.eventPhase == 3
            ? "bubbling"
            : "error";
  divInfo.innerHTML += e.currentTarget.id + "; eventPhase: " + level + "<br/>";
}

function Clear() {
  for (var i = 0; i < divs.length; i++) {
    if (divs[i].id != "divInfo")
      divs[i].style.backgroundColor = i & 1 ? "#f6eedb" : "#cceeff";
  }
  divInfo.innerHTML = "";
}
```

规范
--

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


Event.cancelable - Web API 接口参考

Event.cancelable
================

`Event` 实例的只读属性 **`cancelable`** 表明该事件是否可以被取消，即事件是否可以像从未发生一样被阻止。

如果事件**不能**被取消，则其 `cancelable` 属性的值为 `false`，且事件发生时无法在事件监听回调中停止事件。

大部分由用户与页面交互产生的原生浏览器事件都可以被取消。取消 `click`、`wheel` (en-US) 或 `beforeunload` 事件将分别阻止用户点击某些元素、滚动页面或跳离页面。

使用 JavaScript 代码创建的自定义事件，可以在初始化事件的时候声明该事件是否可以被取消。

要取消一个事件的默认行为，可以调用该事件的 `preventDefault()` 方法。

对于同时处理多种事件的监听回调，可能需要先检查 `cancelable` 属性的值，再调用这些事件的 `preventDefault()` 方法。

值
-

为一个`布尔值` (en-US)。若事件可以被取消，其值为 `true`。

示例
--

例如，浏览器厂商提议 `wheel` (en-US) 事件只能在事件监听回调第一次执行时被取消，接下来的 `wheel` 事件都不能被取消。

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

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

规范
--

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

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

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


Event.originalTarget - Web API 接口参考

Event.originalTarget
====================

**非标准:** 该特性是非标准的，请尽量不要在生产环境中使用它！

**`originalTarget`** 只读属性是事件重定向之前的原始目标。（Mozilla-特有）

在 XBL 的匿名内容中，这将是该事件最初触发的匿名节点。看到匿名的内容。查看Anonymous Content#Event\_Flow\_and\_Targeting 获取更多细节。

注意：原始目标也可能是原生的匿名内容，在这种情况下，它对于非特权代码是无用的。

参见事件目标对比。

规范
--

这是一个 Mozilla 特有的属性，不属于任何规范。它不会成为标准。

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

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


Event.returnValue - Web API 接口参考

Event.returnValue
=================

**`Event.returnValue`** 属性表示该事件的默认操作是否已被阻止。默认情况下，它被设置为 `true`，即允许进行默认操作。将该属性设置为 `false` 即可阻止默认操作。

**备注：** While `returnValue` has been adopted into the DOM standard, it is present primarily to support existing code. You should use `preventDefault()`, and `defaultPrevented` instead of this historical property.

语法
--
```

event.returnValue = bool;

var bool = event.returnValue;
```

### 值

A `Boolean` (en-US) value which is `true` if the event has not been canceled; otherwise, if the event has been canceled or the default has been prevented, the value is `false`.

The value returned by `returnValue` is the opposite of the value returned by `defaultPrevented`.

使用说明
----

`returnValue` was introduced into the DOM by Internet Explorer 6, and due to that browser's ubiquity became so commonly used that other browsers eventually implemented it as well. It has been adopted into the DOM specification, primarily to ensure that existing web content continues to function going forward.

New projects should generally avoid using `returnValue`, although they may if they choose to do so.

规范
--

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

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

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


Event.srcElement - Web API 接口参考

Event.srcElement
================

**非标准:** 该特性是非标准的，请尽量不要在生产环境中使用它！

**`Event.srcElement`** 是标准的 `Event.target` 属性的一个别名。它只对老版本的 IE 浏览器有效。

规范
--

不属于任何规范

微软 **在 MSDN 有一篇描述。**

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

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

参见
--

* `Window.event`


TouchEvent.targetTouches - Web API 接口参考

TouchEvent.targetTouches
========================

**`targetTouches`** 是一个只读的 `TouchList` 列表，包含仍与触摸面接触的所有触摸点的 `Touch` 对象。`touchstart`事件触发在哪个`element`内，它就是当前目标元素。

语法
--

```js
var touches = touchEvent.targetTouches;
```

### 返回值

`touches`

一个 `TouchList`，包含仍与触摸面接触的所有触摸点的 `Touch` 对象，`touchstart`事件触发在哪个`element`内，它就是当前目标元素。

例子
--

本例阐述了 `TouchEvent` 对象的 `TouchEvent.targetTouches` 属性。`TouchEvent.targetTouches` 属性也是一个 `TouchList`，其中包含的触摸点起始于触摸事件当前的目标元素，并且此刻正在触摸屏幕。所以，targetTouches 元素是 `touches` 的真子集。

下面代码段中的函数比较了 `touches` 列表和 `targetTouches` 列表的长度，返回值表示他们是否相等。

```js
function touches\_in\_target(ev) {
  // Return true if all of the touches are within the target element;
  // otherwise return false.
  return ev.touches.length == ev.targetTouches.length ? true : false;
}
```

规范
--

| Specification |
| --- |
| Touch Events # dom-touchevent-targettouches |

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

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


TouchEvent.changedTouches - Web API 接口参考

TouchEvent.changedTouches
=========================

### 概述

这个 `TouchList` 对象列出了和这个触摸事件对应的 `Touch` 对象。

* 对于 `touchstart` 事件，这个 `TouchList` 对象列出在此次事件中新增加的触点。
* 对于 `touchmove` 事件，列出和上一次事件相比较，发生了变化的触点。
* 对于 touchend 事件，**`changedTouches`** 是已经从触摸面的离开的触点的集合（也就是说，手指已经离开了屏幕/触摸面）。
### 语法
```

var touches = touchEvent.changedTouches;
```

这是一个只读属性。

### 返回值

`touches`

列出对应这个触摸事件的 `Touch` 对象的 `TouchList` 对象。

### 标准定义

Touch Events Specification


TouchEvent.touches - Web API 接口参考

TouchEvent.touches
==================

概要
--

一个 `TouchList`，其会列出所有当前在与触摸表面接触的 `Touch` 对象，不管触摸点是否已经改变或其目标元素是在处于 `touchstart` 阶段。

此属性是 只读 。

语法
--
```

var touches = touchEvent.touches;
```

### 返回值

`touches`

一个 `TouchList`，其会列出所有当前在与触摸表面接触的 `Touch` 对象，不管触摸点是否已经改变或其目标元素是在处于 `touchstart` 阶段。

示例
--

此示例说明 `TouchEvent` 对象的 `TouchEvent.touches` 属性。该`TouchEvent.touches` 属性是一个 `TouchList` 对象，并包含 `Touch` 当前接触表面的每个接触点的对象列表。

在下面的代码片段中，`touchstart` 事件处理程序会检查 `TouchEvent.touches` 列表的长度，以确定激活的触摸点的数量，然后根据触摸点的数量调用不同的处理程序。

```js
someElement.addEventListener(
  "touchstart",
  function (e) {
    // Invoke the appropriate handler depending on the
    // number of touch points.
    switch (e.touches.length) {
      case 1:
        handle\_one\_touch(e);
        break;
      case 2:
        handle\_two\_touches(e);
        break;
      case 3:
        handle\_three\_touches(e);
        break;
      default:
        console.log("Not supported");
        break;
    }
  },
  false,
);
```

规范
--

| Specification |
| --- |
| Touch Events # dom-touchevent-touches |

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

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


MediaSource.removeSourceBuffer() - Web API 接口参考

MediaSource.removeSourceBuffer()
================================

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

`MediaSource` 接口的 **`removeSourceBuffer()`** 方法从与 `MediaSource` 对象关联的 `SourceBuffers` 列表中移除给定的 `SourceBuffer`。

语法
--

```js
removeSourceBuffer(sourceBuffer)
```

### 参数

`sourceBuffer`

将被移除的 `SourceBuffer` 对象。

### 返回值

无（`undefined`）。

### 异常

`NotFoundError` `DOMException`

如果提供的 sourceBuffer 在 `MediaSource.sourceBuffers` 中不存在，则抛出异常。

示例
--

```js
for (let i = 0; i < 10; i++) {
  const sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
}

mediaSource.removeSourceBuffer(mediaSource.sourceBuffers[0]);
```

规范
--

| Specification |
| --- |
| Media Source Extensions™ # dom-mediasource-removesourcebuffer |

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

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

参见
--

* `SourceBuffer`
* `SourceBufferList`


MediaSource.addSourceBuffer() - Web API 接口参考

MediaSource.addSourceBuffer()
=============================

`MediaSource` 的 **`addSourceBuffer()`** 方法会根据给定的 MIME 类型创建一个新的 `SourceBuffer` 对象，然后会将它追加到 `MediaSource` 的 `SourceBuffers` 列表中。

语法
--

```js
addSourceBuffer(mimeType)
```

### 参数

mimeType

你想创建的 source buffer 的 MIME 类型。

### 返回值

一个 `SourceBuffer` 对象。

### 异常

`InvalidAccessError` `DOMException`

如果 `mimeType` 指定的值是一个空字符串而不是有效的媒体（MIME）类型，则抛出异常。

`InvalidStateError` `DOMException`

`MediaSource.readyState` 的状态不是 `"open"`，则抛出异常。

`NotSupportedError` `DOMException`

如果用户代理不支持指定的 `mimeType`，或者与媒体源 `sourceBuffer` 列表中已包含的其他 `SourceBuffer` 对象的媒体类型不兼容，则抛出异常。

`QuotaExceededError` `DOMException`

如果用户代理不能处理更多的 `SourceBuffer` 对象，或者使用给定的 `mimeType` 创建了一个新的 `SourceBuffer`，这将导致 `SourceBuffer` 的配置不受支持。

示例
--

以下片段基于 Nick Desaulniers 编写的一个简单示例（查看完整的在线演示，或者下载源代码进行进一步研究）。

```js
const assetURL = "frag\_bunny.mp4";
// Need to be specific for Blink regarding codecs
// ./mp4info frag\_bunny.mp4 | grep Codec
const mimeCodec = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';

if ("MediaSource" in window && MediaSource.isTypeSupported(mimeCodec)) {
  const mediaSource = new MediaSource();
  //console.log(mediaSource.readyState); // closed
  mediaSource.addEventListener("sourceopen", sourceOpen);
  video.src = URL.createObjectURL(mediaSource);
} else {
  console.error("Unsupported MIME type or codec: ", mimeCodec);
}

function sourceOpen() {
  //console.log(this.readyState); // open
  const mediaSource = this;
  const sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
  fetchAB(assetURL, function (buf) {
    sourceBuffer.addEventListener("updateend", () => {
      mediaSource.endOfStream();
      video.play();
      //console.log(mediaSource.readyState); // ended
    });
    sourceBuffer.appendBuffer(buf);
  });
}
```

规范
--

| Specification |
| --- |
| Media Source Extensions™ # dom-mediasource-addsourcebuffer |

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

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

参见
--

* `SourceBuffer`
* `SourceBufferList`


MediaSource.endOfStream() - Web API 接口参考

MediaSource.endOfStream()
=========================

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

`MediaSource` 接口的 **`endOfStream()`** 方法意味着流的结束。

语法
--

```js
mediaSource.endOfStream(endOfStreamError);
```

### 参数

endOfStreamError 可选

一个 `DOMString`，表示当流结束之时需要抛出的异常名。可选的值为：

`network`

中止播放并且发出发生网络错误的信号。这可用于创建一个与媒体流相关的自定义处理程序。例如，你可能有一个与其他网络请求分开的，单独处理媒体分块请求的函数。当你调用 XMLHttpRequest（以获取媒体分块）而触发 `onabort` 或 `onerror` 时，你可能需要调用 `endOfStream('network')`，在 UI 中展示描述性的错误，并且立即重试网络请求或者等到网络恢复（通过某种轮询）。

`decode`

中止播放并且发出发生解码错误的信号。这可用于指示当获取媒体数据时发生了解析错误；可能数据已损坏，或者是使用浏览器不知道如何解码的编解码器进行编码。

### 返回值

无（`undefined`）。

### 异常

`InvalidStateError` `DOMException`

`MediaSource.readyState` 的状态不是 `open`，或者有一个或多个在 `MediaSource.sourceBuffers` 中的 `SourceBuffer` 对象被更新（例如它们的 `SourceBuffer.updating` 属性是 `true`），则抛出该错误。

示例
--

以下片段基于 Nick Desaulniers 编写的一个简单示例（查看完整的在线演示，或者下载源代码进行进一步研究）。

```js
var assetURL = "frag\_bunny.mp4";
// Need to be specific for Blink regarding codecs
// ./mp4info frag\_bunny.mp4 | grep Codec
var mimeCodec = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';

if ("MediaSource" in window && MediaSource.isTypeSupported(mimeCodec)) {
  var mediaSource = new MediaSource();
  //console.log(mediaSource.readyState); // closed
  video.src = URL.createObjectURL(mediaSource);
  mediaSource.addEventListener("sourceopen", sourceOpen);
} else {
  console.error("Unsupported MIME type or codec: ", mimeCodec);
}

function sourceOpen() {
  //console.log(this.readyState); // open
  var mediaSource = this;
  var sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
  fetchAB(assetURL, function (buf) {
    sourceBuffer.addEventListener("updateend", function () => {
      mediaSource.endOfStream();
      video.play();
      //console.log(mediaSource.readyState); // ended
    });
    sourceBuffer.appendBuffer(buf);
  });
}
```

规范
--

| Specification |
| --- |
| Media Source Extensions™ # dom-mediasource-endofstream |

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

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

参见
--

* `SourceBuffer`
* `SourceBufferList`


MediaSource.isTypeSupported() - Web API 接口参考

MediaSource.isTypeSupported()
=============================

**`MediaSource.isTypeSupported()`** 静态方法返回一个布尔值，如果给定的 MIME 类型和（可选的）编解码器*可能*被当前的用户代理支持，则返回 `true`。

也就是说，它可以成功地为该媒体类型创建一个 `SourceBuffer` 对象。如果返回值是 `false`，则用户代理确定它*不*支持指定的媒体格式。

语法
--

```js
isTypeSupported(type)
```

### 参数

`type`

一个指定媒体 MIME 类型的字符串和（可选）包含一个使用逗号分隔的受支持的编解码器集合的`编解码器`参数 (en-US)。

### 返回值

如果给定的媒体类型将*不能*播放，则返回 `false`。

如果浏览器*或许*可以播放给定的媒体类型，则返回 `true`。这不能得到保证，所以你必须为你的代码做好可能无法正常播放媒体的准备。

在确定是否可以使用媒体类型时，所有处理媒体文件的 Web API 都使用“否/可能/或许”方法（或者，在这种情况下，“否或可能”）。这是因为媒体文件是复杂的，它具有太多微妙变化的复杂结构，在你实际使用这个媒体内容之前将无法确定任何事情。

示例
--

以下片段基于 Nick Desaulniers 编写的一个简单示例（查看完整的在线演示，或者下载源代码进行进一步研究）。

```js
const assetURL = "frag\_bunny.mp4";
// Need to be specific for Blink regarding codecs
// ./mp4info frag\_bunny.mp4 | grep Codec
const mimeCodec = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';

if ("MediaSource" in window && MediaSource.isTypeSupported(mimeCodec)) {
  let mediaSource = new MediaSource();
  //console.log(mediaSource.readyState); // closed
  video.src = URL.createObjectURL(mediaSource);
  mediaSource.addEventListener("sourceopen", sourceOpen);
} else {
  console.error("Unsupported MIME type or codec: ", mimeCodec);
}

function sourceOpen() {
  //console.log(this.readyState); // open
  let mediaSource = this;
  let sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
  fetchAB(assetURL, function (buf) {
    sourceBuffer.addEventListener("updateend", () => {
      mediaSource.endOfStream();
      video.play();
      //console.log(mediaSource.readyState); // ended
    });
    sourceBuffer.appendBuffer(buf);
  });
}
```

规范
--

| Specification |
| --- |
| Media Source Extensions™ # dom-mediasource-istypesupported |

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

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

参见
--

* Media Source Extensions API
* Guide to media types and formats on the web
* The "codecs" parameter in common media types (en-US)
* `SourceBuffer`
* `SourceBufferList`


MediaSource.sourceBuffers - Web API 接口参考

MediaSource.sourceBuffers
=========================

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

`MediaSource` 接口的只读属性 **`sourceBuffers`** 返回一个 `SourceBufferList` 对象，该对象包含着与 `MediaSource` 关联的 `SourceBuffer` 对象列表。

值
-

一个 `SourceBufferList`。

示例
--

以下片段基于 Nick Desaulniers 编写的一个简单示例（查看完整的在线演示，或者下载源代码进行进一步研究）。

```js
function sourceOpen() {
  //console.log(this.readyState); // open
  const mediaSource = this;
  const sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
  fetchAB(assetURL, function (buf) {
    sourceBuffer.addEventListener("updateend", () => {
      mediaSource.endOfStream();
      console.log(mediaSource.sourceBuffers); // will contain the source buffer that was added above
      video.play();
      //console.log(mediaSource.readyState); // ended
    });
    sourceBuffer.appendBuffer(buf);
  });
}

// …
```

规范
--

| Specification |
| --- |
| Media Source Extensions™ # dom-mediasource-sourcebuffers |

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

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

参见
--

* `SourceBuffer`
* `SourceBufferList`


MediaSource.MediaSource() - Web API 接口参考

MediaSource.MediaSource()
=========================

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

**`MediaSource()`** 是 `MediaSource` 的构造函数，返回一个没有分配 source buffers 新的 `MediaSource` 对象。

语法
--

```js
new MediaSource()
```

### 参数

无。

示例
--

以下片段基于 Nick Desaulniers 编写的一个简单示例（查看完整的在线演示，或者下载源代码进行进一步研究）。

```js
var video = document.querySelector("video");

var assetURL = "frag\_bunny.mp4";
// Need to be specific for Blink regarding codecs
// ./mp4info frag\_bunny.mp4 | grep Codec
var mimeCodec = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';

if ("MediaSource" in window && MediaSource.isTypeSupported(mimeCodec)) {
  var mediaSource = new MediaSource();
  //console.log(mediaSource.readyState); // closed
  video.src = URL.createObjectURL(mediaSource);
  mediaSource.addEventListener("sourceopen", sourceOpen);
} else {
  console.error("Unsupported MIME type or codec: ", mimeCodec);
}

// …
```

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

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

参见
--

* `SourceBuffer`
* `SourceBufferList`


MediaSource.readyState - Web API 接口参考

MediaSource.readyState
======================

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

\*\*`readyState`\*\*是 `MediaSource` 接口的一个只读属性。它返回一个集合表明当前 `MediaSource` 的状态。它有三种可能的返回值：

* `closed`：当前源并未附着到一个 media 元素上。
* `open`：当前源已附着到一个 media 元素并准备好接收 `SourceBuffer` 对象。
* `ended`：当前源已附着到一个 media 元素，但流已被 `MediaSource.endOfStream()` 结束。
语法
--

```js
var myReadyState = mediaSource.readyState;
```

### 值

一个 `DOMString`。

示例
--

以下片段基于 Nick Desaulniers 编写的一个简单示例（查看完整的在线演示，或者下载源代码进行进一步研究）。

```js
if ("MediaSource" in window && MediaSource.isTypeSupported(mimeCodec)) {
  var mediaSource = new MediaSource();
  //console.log(mediaSource.readyState); // closed
  video.src = URL.createObjectURL(mediaSource);
  mediaSource.addEventListener("sourceopen", sourceOpen);
} else {
  console.error("Unsupported MIME type or codec: ", mimeCodec);
}

function sourceOpen(\_) {
  //console.log(this.readyState); // open
  var mediaSource = this;
  var sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
  fetchAB(assetURL, function (buf) {
    sourceBuffer.addEventListener("updateend", function (\_) {
      mediaSource.endOfStream();
      video.play();
      //console.log(mediaSource.readyState); // ended
    });
    sourceBuffer.appendBuffer(buf);
  });
}
```

规范
--

| Specification |
| --- |
| Media Source Extensions™ # dom-mediasource-readystate |

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

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

参见
--

* `SourceBuffer`
* `SourceBufferList`


MediaSource.duration - Web API 接口参考

MediaSource.duration
====================

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

`MediaSource` 接口的属性 **`duration`** 用来获取或者设置当前媒体展示的时长。

### 值

以秒为单位的双精度浮点数。

### 异常

设置新的值的时候可能会有下面的错误抛出。

`InvalidAccessError` `DOMException`

时长尝试设置一个负数，或者为 `NaN` 则抛出。

`InvalidStateError` `DOMException`

`MediaSource.readyState` 的状态不是 `open`，或者有一个或多个在 `MediaSource.sourceBuffers` 中的 `SourceBuffer` 对象被更新（例如它们的 `SourceBuffer.updating` 属性是 `true`），则抛出该错误。

示例
--

以下片段基于 Nick Desaulniers 编写的一个简单示例（查看完整的在线演示，或者下载源代码进行进一步研究）。

```js
function sourceOpen() {
  //console.log(this.readyState); // open
  const mediaSource = this;
  const sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
  fetchAB(assetURL, function (buf) {
    sourceBuffer.addEventListener("updateend", () => {
      mediaSource.endOfStream();
      mediaSource.duration = 120;
      video.play();
      //console.log(mediaSource.readyState); // ended
    });
    sourceBuffer.appendBuffer(buf);
  });
}

// …
```

规范
--

| Specification |
| --- |
| Media Source Extensions™ # dom-mediasource-duration |

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

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

参见
--

* `SourceBuffer`
* `SourceBufferList`


MediaSource.activeSourceBuffers - Web API 接口参考

MediaSource.activeSourceBuffers
===============================

`MediaSource` 接口的只读属性 **`activeSourceBuffers`** 返回一个 `SourceBufferList` 对象，该对象包含了 `sourceBuffers` 中的 `SourceBuffer` 对象的子集——提供当前所选的视频轨道、启用的音频轨道和显示或者隐藏的字幕轨道的对象列表。

值
-

一个 `SourceBufferList`，包含每个活动轨道的 `SourceBuffer` 对象。

示例
--

以下片段基于 Nick Desaulniers 编写的一个简单示例（查看完整的在线演示，或者下载源代码进行进一步研究）。

```js
function sourceOpen() {
  //console.log(this.readyState); // open
  const mediaSource = this;
  const sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
  fetchAB(assetURL, function (buf) {
    sourceBuffer.addEventListener("updateend", () => {
      mediaSource.endOfStream();
      console.log(mediaSource.activeSourceBuffers);
      // will contain the source buffer that was added above,
      // as it is selected for playing in the video player
      video.play();
      //console.log(mediaSource.readyState); // ended
    });
    sourceBuffer.appendBuffer(buf);
  });
}

// …
```

规范
--

| Specification |
| --- |
| Media Source Extensions™ # dom-mediasource-activesourcebuffers |

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

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

参见
--

* `SourceBuffer`
* `SourceBufferList`


MediaRecorder.isTypeSupported - Web API 接口参考

MediaRecorder.isTypeSupported
=============================

\*\*`MediaRecorder.isTypeSupported()`\*\*方法会判断其 MIME 格式能否被客户端录制。

语法
--
```

var canRecord = MediaRecorder.isTypeSupported(mimeType)
```

### 参数

`mimeType`

需要检查的 MIME 格式

### 返回值

如果 `MediaRecorder` 在浏览器上的具体实现能够支持指定 MIME 类型的 `Blob` 对象就返回 true. 如果没有足够的资源来支持录制和编码任务，最终录制依然会失败。如果返回结果是 false，用户的浏览器就无法录制指定的格式。

Example
-------

```js
var types = [
  "video/webm",
  "audio/webm",
  "video/webm;codecs=vp8",
  "video/webm;codecs=daala",
  "video/webm;codecs=h264",
  "audio/webm;codecs=opus",
  "video/mpeg",
];

for (var i in types) {
  console.log(
    "Is " +
      types[i] +
      " supported? " +
      (MediaRecorder.isTypeSupported(types[i]) ? "Maybe!" : "Nope :("),
  );
}
```

规范
--

| Specification |
| --- |
| MediaStream Recording # dom-mediarecorder-istypesupported |

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

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

看过这个的用户还浏览了以下内容：
----------------

* Using Service Workers (en-US)
* `MediaStreamTrack`
* `MediaStream`


MediaRecorder.audioBitsPerSecond - Web API 接口参考

MediaRecorder.audioBitsPerSecond
================================

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

**`audioBitsPerSecond`** `MediaRecorder` 接口的只读属性。它返回录制器所使用的音频编码码率。或许与构造函数中指定的比特率有些不同（如果调用构造函数的时候有指定）。

语法
--
```

var audioBitsPerSecond = MediaRecorder.audioBitsPerSecond
```

### 值

`Number` (无符号长整型).

规范
--

| Specification |
| --- |
| MediaStream Recording # dom-mediarecorder-audiobitspersecond |

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

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


MediaRecorder() - Web API 接口参考

MediaRecorder()
===============

**`MediaRecorder()`** 构造函数会创建一个对指定的 `MediaStream` 进行录制的 `MediaRecorder` 对象

语法
--
```

var mediaRecorder = new MediaRecorder(stream[, options]);
```

### 参数

**`stream`**

`MediaStream` 将要录制的流。它可以是来自于使用 `navigator.mediaDevices.getUserMedia()` 创建的流或者来自于 `<audio>`, `<video>` 以及 `<canvas>` DOM 元素。

**`options`** 可选

一个字典对象，它可以包含下列属性：

* `mimeType`: 为新构建的 `MediaRecorder` 指定录制容器的 MIME 类型。在应用中通过调用 `MediaRecorder.isTypeSupported()` 来检查浏览器是否支持此种`mimeType` .
* `audioBitsPerSecond`: 指定音频的比特率。
* `videoBitsPerSecond`: 指定视频的比特率。
* `bitsPerSecond`: 指定音频和视频的比特率。此属性可以用来指定上面两个属性。如果上面两个属性只有其中之一和此属性被指定，则此属性可以用于设定另外一个属性。

**备注：** 如果视频和/或音频的比特率没有指定，视频默认采用的比特率是 2.5Mbps，但音频的默认比特率并不固定，音频的默认比特率根据采样率和轨道数自适应。

例子
--

此例展示了如果对指定的流创建一个音频比特率为 128kbps，视频比特率为 2.5Mbps 的媒体录制器。被录制的媒体数据会以 MP4 格式封装 (因此你若获取这些媒体数据片段，并存放到磁盘上去，你就会得到一个 mp4 文件).

```js
...

if (navigator.mediaDevices.getUserMedia) {
  var constraints = { audio: true, video: true };
  var chunks = [];

  var onSuccess = function(stream) {
    var options = {
      audioBitsPerSecond : 128000,
      videoBitsPerSecond : 2500000,
      mimeType : 'video/mp4'
    }
    var mediaRecorder = new MediaRecorder(stream,options);
    m = mediaRecorder;

...
```

规范
--

| Specification |
| --- |
| MediaStream Recording # dom-mediarecorder-mediarecorder |

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

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

更多信息
----

* Using the MediaRecorder API (en-US)
* Web Dictaphone: MediaRecorder + getUserMedia + Web Audio API visualization demo, by Chris Mills (source on Github.)
* simpl.info MediaStream Recording demo, by Sam Dutton.
* `Navigator.mediaDevices.getUserMedia()` (en-US)


MediaRecorder.ondataavailable - Web API 接口参考

MediaRecorder.ondataavailable
=============================

**`MediaRecorder.ondataavailable`** 事件处理程序 (part of the MediaStream 记录 API) 处理 `dataavailable` 事件，让你在响应运行代码`Blob`数据被提供使用。

`dataavailable`当 MediaRecorder 将媒体数据传递到你的应用程序以供使用时，将触发该事件。数据在包含数据的`Blob`对象中提供。这在四种情况下发生：

* 媒体流结束时，所有尚未传递到`ondataavailable`处理程序的媒体数据都将在单个`Blob`中传递。
* 当调用`MediaRecorder.stop()` (en-US)时，自记录开始或`dataavailable`事件最后一次发生以来已捕获的所有媒体数据都将传递到`Blob`中；此后，捕获结束。
* 调用`MediaRecorder.requestData()` (en-US) `dataavailable`时，将传递自记录开始或事件最后一次发生以来捕获的所有媒体数据；然后`Blob`创建一个新文件，并将媒体捕获继续到该 blob 中。
* 如果将`timeslice`属性传递到开始媒体捕获的`MediaRecorder.start()` (en-US)方法中，`dataavailable`则每`timeslice`毫秒触发一次事件。这意味着每个 Blob 都有特定的持续时间（最后一个 Blob 除外，后者可能更短，因为它将是自上次事件以来剩下的所有东西）。因此，如果该方法调用看起来像这样 - `recorder.start(1000);`-的`dataavailable`事件将媒体捕捉的每一秒发生火灾后，我们的事件处理程序将被称为与媒体数据的 BLOB 每秒即坚持一个第二长。你可以`timeslice`与`MediaRecorder.stop()` (en-US)和`MediaRecorder.requestData()` (en-US)一起使用，以产生多个相同长度的 Blob，以及其他较短的 Blob。

**备注：** 包含媒体数据的 `Blob` 在 `dataavailable` 事件的 `data` 属性中可用。

语法
--
```

MediaRecorder.ondataavailable = function(event) { ... }
MediaRecorder.addEventListener('dataavailable', function(event) { ... })
```

示例
--
```

...
  var chunks = [];

  mediaRecorder.onstop = function(e) {
    console.log("data available after MediaRecorder.stop() called.");

    var audio = document.createElement('audio');
    audio.controls = true;
    var blob = new Blob(chunks, { 'type' : 'audio/ogg; codecs=opus' });
    var audioURL = window.URL.createObjectURL(blob);
    audio.src = audioURL;
    console.log("录像停止");
  }

  mediaRecorder.ondataavailable = function(e) {
    chunks.push(e.data);
  }

...
```

规范
--

| Specification |
| --- |
| MediaStream Recording # dom-mediarecorder-ondataavailable |

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

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

参见
--

* 使用 MediaStream 录制 API
* Web Dictaphone：Chris Mills 提供的 MediaRecorder + getUserMedia + Web Audio API 可视化演示 (在 Github 上提供)。
* simpl.info MediaStream 录制演示，作者Sam Dutton。
* `Navigator.getUserMedia`


SpeechSynthesis.paused - Web API 接口参考

SpeechSynthesis.paused
======================

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

`SpeechSynthesis` 接口的只读属性 **`paused`** 是一个 `Boolean` (en-US) 值，当`SpeechSynthesis`对象处于暂停状态时，返回`true` ，否则返回 `false`。

它能被设置为 `暂停状态` (en-US) 即使当前并没有语音在播放队列中。如果`utterances` (en-US) 被添加到语音播放队列，队列中的语音并不会播放直到使用 `SpeechSynthesis.resume()` (en-US)使`SpeechSynthesis`对象处于非暂停状态。

语法
--
```

var amIPaused = speechSynthesisInstance.paused;
```

### Value

一个`Boolean` (en-US)。

示例
--

```js
var synth = window.speechSynthesis;

synth.pause();

var amIPaused = synth.paused; // 将返回 true
```

规范
--

| Specification |
| --- |
| Web Speech API # dom-speechsynthesis-paused |

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

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

请参阅
---

* Web Speech API


SpeechSynthesis.getVoices() - Web API 接口参考

SpeechSynthesis.getVoices()
===========================

`SpeechSynthesis` 接口的 **`getVoices()`** 方法返回一个 `SpeechSynthesisVoice` (en-US) 列表，用于表示当前设备上所有可用的语音。

语法
--

```js
getVoices()
```

### 参数

无。

### 返回值

返回一个类型为 `SpeechSynthesisVoice` (en-US) 的数组（array）列表（list）。

示例
--

### JavaScript

```js
function populateVoiceList() {
  if (typeof speechSynthesis === "undefined") {
    return;
  }
  var voices = speechSynthesis.getVoices();
  for (var i = 0; i < voices.length; i++) {
    var option = document.createElement("option");
    option.textContent = voices[i].name + " (" + voices[i].lang + ")";
    if (voices[i].default) {
      option.textContent += " -- DEFAULT";
    }
    option.setAttribute("data-lang", voices[i].lang);
    option.setAttribute("data-name", voices[i].name);
    document.getElementById("voiceSelect").appendChild(option);
  }
}
populateVoiceList();
if (
  typeof speechSynthesis !== "undefined" &&
  speechSynthesis.onvoiceschanged !== undefined
) {
  speechSynthesis.onvoiceschanged = populateVoiceList;
}
```

### HTML

```html
<select id="voiceSelect"></select>
```

规范
--

| Specification |
| --- |
| Web Speech API # dom-speechsynthesis-getvoices |

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

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

参见
--

* Web Speech API


EventSource.onerror - Web API 接口参考

EventSource.onerror
===================

`EventSource` 的属性 **`onerror`** 是当发生错误且这个错误事件（`error`）被 EventSource 触发时调用的一个事件处理函数。

语法
--
```

eventSource.onerror = function
```

例子
--

```js
evtSource.onerror = function () {
  console.log("EventSource failed.");
};
```

**备注：** 你可以在 Github 上查看这个完整例子： Simple SSE demo using PHP.

规范
--

| Specification |
| --- |
| HTML Standard # event-error |
| HTML Standard # handler-eventsource-onerror |

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

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

参见
--

* `EventSource`


EventSource() - Web API 接口参考

EventSource()
=============

**`EventSource()`** 构造函数返回一个新建的`EventSource`，它代表了一个远程资源。

语法
--
```

pc = new EventSource(url, configuration);
```

### 参数

`url`

一个`USVString` ，它代表远程资源的位置

`configuration` 可选

为配置新连接提供选项。可选项是：

* `withCredentials`，默认为 `false`，指示 CORS 是否应包含凭据 ( credentials )。

### 返回值

一个新建的 `EventSource` 对象，如果指定了`configuration`，则按其配置；否则，配置为合适的基本默认值。

示例
--

```js
var evtSource = new EventSource("sse.php");
var eventList = document.querySelector("ul");

evtSource.onmessage = function (e) {
  var newElement = document.createElement("li");

  newElement.textContent = "message: " + e.data;
  eventList.appendChild(newElement);
};
```

**备注：** 你可以在 GitHub 查看完整示例 — 请查看 Simple SSE demo using PHP.

规范
--

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

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

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

参见
--

* `EventSource`


EventSource.onopen - Web API 接口参考

EventSource.onopen
==================

`EventSource`接口的 **`onopen`** 属性是一个事件处理器，它在收到 `open` 事件时被调用，在那时，连接刚被打开。

语法
--
```

eventSource.onopen = function
```

示例
--

```js
evtSource.onopen = function () {
  console.log("Connection to server opened.");
};
```

**备注：** 你可以在 GitHub 上看到一个完整的示例— 请看 使用 php 的 SSE(服务器发送事件)demo。

规范
--

| Specification |
| --- |
| HTML Standard # event-open |
| HTML Standard # handler-eventsource-onopen |

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

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

参见
--

* `EventSource`


EventSource：message 事件 - Web API 接口参考

EventSource：message 事件
======================

`EventSource` API 的 `message` 事件，会在通过事件源收到数据时触发。

此事件不能取消，也不会冒泡。

语法
--

在如 `addEventListener()` 等方法中使用事件名称，或者设置事件处理器属性。

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

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

事件类型
----

*一个 `MessageEvent`。继承自 `Event`。*

Event

MessageEvent事件属性
----

*本接口也继承了父接口 `Event` 的属性。*

`MessageEvent.data` (en-US) 只读

消息发射器发出的数据。

`MessageEvent.origin` (en-US) 只读

一个字符串，表示消息发射器的源（origin）。

`MessageEvent.lastEventId` (en-US) 只读

一个字符串，表示事件的唯一 ID。

`MessageEvent.source` (en-US) 只读

一个 `MessageEventSource`（可以是一个 WindowProxy (en-US)、`MessagePort` 或 `ServiceWorker` 对象），表示事件发射器。

`MessageEvent.ports` (en-US) 只读

一个 `MessagePort` 对象的数组，表示与正在发送消息的通道相关联的端口（如果适用，例如在传递通道消息，或者向共享的 worker 发送消息时）。

示例
--

在这个基本示例中，创建了一个 `EventSource` 对象来接收来自服务器的事件；名为 `sse.php` 的页面负责生成这些事件。

```js
const evtSource = new EventSource("sse.php");
const eventList = document.querySelector("ul");

evtSource.addEventListener("message", (e) => {
  const newElement = document.createElement("li");

  newElement.textContent = `message: ${e.data}`;
  eventList.appendChild(newElement);
});
```

### onmessage 的等价写法

```js
evtSource.onmessage = (e) => {
  const newElement = document.createElement("li");

  newElement.textContent = `message: ${e.data}`;
  eventList.appendChild(newElement);
};
```

规范
--

| Specification |
| --- |
| HTML Standard # event-message |
| HTML Standard # handler-eventsource-onmessage |

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

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

参见
--

* 使用 Server-sent 事件
* `open`
* `error`


EventSource.close() - Web API 接口参考

EventSource.close()
===================

`EventSource` 的方法 **`close()`** 用于关闭当前的连接，如果调用了此方法，则会将`EventSource.readyState` (en-US)这个属性值设置为 2 (closed)

**备注：** 如果连接已经被关闭，此方法不会做任何事情

语法
--
```

eventSource.close();
```

### 参数

None.

### 返回值

Void.

例子
--

```js
var button = document.querySelector("button");
var evtSource = new EventSource("sse.php");

button.onclick = function () {
  console.log("Connection closed");
  evtSource.close();
};
```

**备注：** 你可以在 Github 上查看这整个例子： Simple SSE demo using PHP.

规范
--

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

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

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

参见
--

* `EventSource`


RTCRtpTransceiver.direction - Web API 接口参考

RTCRtpTransceiver.direction
===========================

The `RTCRtpTransceiver` (en-US) property **`direction`** is a string which indicates the transceiver's preferred directionality. Its value must be one of the strings defined by the `RTCRtpTransceiverDirection` (en-US) enumeration.

The transceiver's *current* direction is indicated by the `currentDirection` (en-US) property.

### 值

A `DOMString` whose value is one of the strings which are a member of the `RTCRtpTransceiverDirection` enumerated type, indicating the transceiver's preferred direction.

| 值 | `RTCRtpSender` 的行为 | `RTCRtpReceiver` 的行为 |
| --- | --- | --- |
| `"sendrecv"` | 可以发送 RTP (en-US) 数据，如果另一个对等节点接受了连接，且至少有一个 sender 的处于编码状态，则发送数据。 | 可以接收 RTP 数据，如果有其他的对等节点接受数据，则接收数据。 |
| `"sendonly"` | 可以发送 RTP (en-US) 数据，如果另一个对等节点接受了连接，且至少有一个 sender 的处于编码状态，则发送数据。 | *不*可以接收 RTP 数据，无论如何都不会接收数据。 |
| `"recvonly"` | *不*可以发送 RTP 数据，无论如何都不会发送数据。 | 可以接收 RTP 数据，如果有其他的对等节点接受数据，则接收数据。 |
| `"inactive"` | *不*可以发送 RTP 数据，无论如何都不会发送数据。 | *不*可以接收 RTP 数据，无论如何都不会接收数据。 |

### 异常

When setting the value of `direction`, the following exceptions can occur:

`InvalidStateError`

Either the receiver's `RTCPeerConnection` is closed or the `RTCRtpReceiver` (en-US) is stopped.

Usage notes
-----------

### Setting the direction

When you change the value of `direction`, an `InvalidStateError` exception will occur if the connection is closed or the receiver is stopped.

If the new value of `direction` is in fact different from the existing value, renegotiation of the connection is required, so a `negotiationneeded` (en-US) event is sent to the `RTCPeerConnection`.

### Effect on offers and answers

The value of `direction` is used by `RTCPeerConnection.createOffer()` or `RTCPeerConnection.createAnswer()` (en-US) in order to generate the SDP generated by each of those methods. The SDP contains an a-line which specifies the directionality. For example, if the `direction` is specified as `"sendrecv"`, the corresponding SDP a-line is:
```

a=sendrecv
```

规范
--

| Specification |
| --- |
| WebRTC: Real-Time Communication in Browsers # dom-rtcrtptransceiver-direction |

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

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

参见
--

* `RTCRtpTransceiver.currentDirection` (en-US)


TimeRanges.start() - Web API 接口参考

TimeRanges.start()
==================

返回指定时间范围的开始偏移量。

语法
--
```

startTime = TimeRanges.start(index)
```

### 参数

* `index` 想要检索的时间范围的索引值。
### 异常

INDEX\_SIZE\_ERR

如果不存在指定索引值的时间范围，抛出 `DOMException` 异常。

示例
--

假定页面中存在一个 ID 为“myVideo”的 video 元素：

```js
var v = document.getElementById("myVideo");

var buf = v.buffered;

var numRanges = buf.length;

if (buf.length == 1) {
  // only one range
  if (buf.start(0) == 0 && buf.end(0) == v.duration) {
    // The one range starts at the beginning and ends at
    // the end of the video, so the whole thing is loaded
  }
}
```

这个例子演示了如何通过 `TimeRanges` 来判断 video 是否已经完全加载。

规范
--

| Specification |
| --- |
| HTML Standard # dom-timeranges-start-dev |

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

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


TimeRanges.end() - Web API 接口参考

TimeRanges.end()
================

返回指定时间范围的结束偏移量。

语法
--
```

endTime = TimeRanges.end(index)
```

### 参数

* `index` 想要检索的时间范围的索引值。
### 异常

INDEX\_SIZE\_ERR

如果不存在指定索引值的时间范围，抛出 `DOMException` 异常。

示例
--

假定页面中存在一个 ID 为“myVideo”的 video 元素：

```js
var v = document.getElementById("myVideo");

var buf = v.buffered;

var numRanges = buf.length;

if (buf.length == 1) {
  // only one range
  if (buf.start(0) == 0 && buf.end(0) == v.duration) {
    // The one range starts at the beginning and ends at
    // the end of the video, so the whole thing is loaded
  }
}
```

这个例子演示了如何通过 `TimeRanges` 来判断 video 是否已经完全加载。

规范
--

| Specification |
| --- |
| HTML Standard # dom-timeranges-end-dev |

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

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


TimeRanges.length - Web API 接口参考

TimeRanges.length
=================

只读属性 **`TimeRanges.length`** 返回对象中时间范围的个数。

语法
--
```

length = TimeRanges.length;
```

示例
--

假定页面中存在一个 ID 为“myVideo”的 video 元素：

```js
var v = document.GetElementById("myVideo");

var buf = v.buffered;

var numRanges = buf.length;

if (buf.length == 1) {
  // Only one range
  if (buf.start(0) == 0 && buf.end(0) == v.duration) {
    // The one range starts at the beginning and ends at
    // the end of the video, so the whole thing is loaded
  }
}
```

这个例子演示了如何通过 `TimeRanges` 来判断 video 是否已经完全加载。

规范
--

| Specification |
| --- |
| HTML Standard # dom-timeranges-length-dev |

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

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


ByteLengthQueuingStrategy() - Web API 接口参考

ByteLengthQueuingStrategy()
===========================

**`ByteLengthQueuingStrategy()`** 构造函数创建并返回一个 `ByteLengthQueuingStrategy` 对象实例。

语法
--

```js
new ByteLengthQueuingStrategy(highWaterMark)
```

### 参数

`highWaterMark`

一个包含 `highWaterMark` 属性的对象。这个属性是一个非负整数，定义了在应用背压之前内部队列可以包含的分块的总数。

### 返回值

一个 `ByteLengthQueuingStrategy` 对象实例。

### 异常

无。

示例
--

```js
const queuingStrategy = new ByteLengthQueuingStrategy({ highWaterMark: 1 });

const readableStream = new ReadableStream(
  {
    start(controller) {
      // …
    },
    pull(controller) {
      // …
    },
    cancel(err) {
      console.log("stream error:", err);
    },
  },
  queuingStrategy,
);

const size = queuingStrategy.size(chunk);
```

规范
--

| Specification |
| --- |
| Streams Standard # blqs-constructor |

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

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

参见
--

* `ByteLengthQueuingStrategy` 接口


ByteLengthQueuingStrategy.size() - Web API 接口参考

ByteLengthQueuingStrategy.size()
================================

`ByteLengthQueuingStrategy` 接口的 **`size()`** 方法返回给定分块的 `byteLength` 属性。

语法
--

```js
size(chunk)
```

### 参数

`chunk`

一个通过流传递的数据分块。

### 返回值

一个整数，表示给定分块的字节长度。

示例
--

```js
const queuingStrategy = new ByteLengthQueuingStrategy({ highWaterMark: 1 });

const readableStream = new ReadableStream(
  {
    start(controller) {
      // …
    },
    pull(controller) {
      // …
    },
    cancel(err) {
      console.log("stream error:", err);
    },
  },
  queuingStrategy,
);

const size = queueingStrategy.size(chunk);
```

规范
--

| Specification |
| --- |
| Streams Standard # blqs-size |

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

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

参见
--

* `ByteLengthQueuingStrategy()` 构造函数


ByteLengthQueuingStrategy：highWaterMark 属性 - Web API 接口参考

ByteLengthQueuingStrategy：highWaterMark 属性
==========================================

只读属性 **`ByteLengthQueuingStrategy.highWaterMark`** 返回在应用背压之前，内置队列可以包含的字节总数。

**备注：** 与 `CountQueuingStrategy()` 不同，后者的 `highWaterMark` 指定了分块的数量，`ByteLengthQueuingStrategy()` 的 `highWaterMark` 参数则指定了*字节*数量——具体地说，给定一个分块流，在应用背压之前，内部队列可以包含这些分块的字节数（而不是这些分块的数量）。

值
-

一个整数。

示例
--

```js
const queuingStrategy = new ByteLengthQueuingStrategy({
  highWaterMark: 1 \* 1024,
});

const readableStream = new ReadableStream(
  {
    start(controller) {
      // …
    },
    pull(controller) {
      // …
    },
    cancel(err) {
      console.log("stream error:", err);
    },
  },
  queuingStrategy,
);

const size = queuingStrategy.size(chunk);
console.log(`highWaterMark value: ${queuingStrategy.highWaterMark}$`);
```

规范
--

| Specification |
| --- |
| Streams Standard # ref-for-blqs-high-water-mark① |

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

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

参见
--

* `ByteLengthQueuingStrategy()` 构造函数


Attr.namespaceURI - Web API 接口参考

Attr.namespaceURI
=================

**`Attr.namespaceURI`** 只读属性返回属性的命名空间 URI，如果该元素不在命名空间中，则返回 null。

**备注：** 在 DOM4 之前，该 API 是在 `Node` 中定义的。

语法
--
```

namespace = attribute.namespaceURI
```

例子
--

在这个片段中，正在检查一个属性的 `localName` 和 `namespaceURI`。如果 `namespaceURI` 返回 XUL 命名空间，并且 localName 返回 "browser"，则该节点被理解为 XUL `<browser/>`。

```js
if (
  attribute.localName == "value" &&
  attribute.namespaceURI ==
    "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
) {
  // this is a XUL value
}
```

笔记
--

 这不是基于对范围中的命名空间声明的检查的命名空间查找的结果的计算值。
 属性的命名空间 URI 在属性创建时被冻结。

 在 Firefox 3.5 及更早版本中，HTML 文档中 HTML 属性的命名空间 URI 为 null。
 在后来的版本中，遵照 HTML5，就像在 XHTML 中一样是`https://www.w3.org/1999/xhtml`

你可以使用 DOM Level 2 方法 `Element.setAttributeNS`创建具有指定 namespaceURI 的属性。

 根据 Namespaces in XML 规范，属性不会从其附加的元素继承其命名空间。
 如果一个属性没有明确地给出一个命名空间，它没有命名空间。

 DOM 本身不处理或强制命名空间验证。DOM 应用程序需要做任何必要的验证。
 还要注意，一旦与特定节点相关联，命名空间前缀将无法更改。

规格
--

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

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

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

其他文章
----

* `Attr.localName`
* `Attr.prefix`
* `Element.namespaceURI`
* `Node.namespaceURI` (en-US)


Attr.localName - Web API 接口参考

Attr.localName
==============

**`Attr.localName`** 为只读属性，返回一个属性限定名称的本名部分（去除命名空间前缀的名字）。

**备注：** 在之前的 DOM 规范中此 API 被定义在 `Node` 接口中。

语法
--
```

name = attribute.localName
```

### 返回值

属性的限定名称的本名 `DOMString` 。

示例
--

下面的例子将弹出一个有“id”文字的警告窗口。

### HTML

```html
<button id="example">Click me</button>
```

### JavaScript

```js
const element = document.querySelector("#example");
element.addEventListener("click", function () {
  const attribute = element.attributes[0];
  alert(attribute.localName);
});
```

注意
--

本文档中属性的“本名 (local name)”指的是属性“限定名称 (qualified names)”的命名空间冒号之后的部分。“限定名称”通常作为 XML 文档命名空间的一部分用在 XML 代码内。

**备注：** 在 Gecko 1.9.2 以及跟早的版本中，HTML DOM 访问该属性将返回 HTML 节点属性的大写字符串本名（有别于 XML DOM 的 XHTML 属性）。在后来的版本中，为遵循 HTML5 标准，该属性返回 DOM 内部存储的名称，即，不论 HTML DOM 的 HTML 属性还是 XML DOM 的 XHTML 属性都是小写字符串。

规范
--

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

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

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

参考
--

* `Attr.namespaceURI`
* `Attr.prefix`
* `Element.localName`
* `Node.localName` (en-US)


Attr.prefix - Web API 接口参考

Attr.prefix
===========

**`Attr.prefix`** 为只读属性，返回指定标签属性的名字空间前缀，如果没有前缀则返回 `null`。

**备注：** 在 DOM4 之前此 API 被定义在 `Node` 接口中。

语法
--
```

string = attribute.prefix
```

示例
--

下例在控制台中输出“x”。

```xml
<div x:id="example" onclick="console.log(this.attributes[0].prefix)"/>
```

注意
--

该属性仅在使用有名字空间解析功能的解析器时有效，例如一个 MIME 类型为 XML 的文档。在 HTML 文档中无效。

规范
--

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

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

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

参考
--

* `Attr.namespaceURI`
* `Attr.localName`
* `Element.prefix`
* `Node.prefix` (en-US)