FileReader - Web APIs

FileReader
==========

藉由 `FileReader` 物件，Web 應用程式能以非同步（asynchronously）方式讀取儲存在用戶端的檔案（或原始資料暫存）內容，可以使用 `File` 或 `Blob` 物件指定要讀取的資料。

File 物件可以從使用者於 `<input>` (en-US) 元素選擇之檔案所回傳的 `FileList` 物件當中取得，或是來自拖放操作所產生的 `DataTransfer` (en-US) 物件之中，也能由 `HTMLCanvasElement` (en-US) 物件（元素物件）執行 `mozGetAsFile()` 方法後回傳。

**備註：** 此功能可在 Web Worker (en-US) 中使用

建構式
---

`FileReader()` (en-US)

建立新的 `FileReader` 物件。

請參考在網頁應用程式中使用本地檔案的更多細節與範例。

屬性
--

`FileReader.error` Read only

此 `DOMException` (en-US) 類型的物件記錄了讀取資料時發生的錯誤資訊。

`FileReader.readyState` Read only

表示目前 `FileReader` 狀態的數字，其代表的意義為：

|  |  |  |
| --- | --- | --- |
| `EMPTY` | `0` | 尚未讀入任何資料。 |
| `LOADING` | `1` | 正在讀入資料。 |
| `DONE` | `2` | 完成資料讀取。 |

`FileReader.result` (en-US) Read only

讀入的資料內容。只有在讀取完成之後此屬性才有效，而資料的格式則取決於是由哪一個方法進行讀取。

### 事件處理器

`FileReader.onabort` (en-US)

`abort` 事件處理器，於讀取被中斷時觸發。

`FileReader.onerror` (en-US)

`error` (en-US) 事件處理器，於讀取發生錯誤時觸發。

`FileReader.onload` (en-US)

`load` (en-US) 事件處理器，於讀取完成時觸發。

`FileReader.onloadstart`

`loadstart` (en-US) 事件處理器，於讀取開始時觸發。

`FileReader.onloadend`

`loadend` (en-US) 事件處理器，於每一次讀取結束之後觸發（不論成功或失敗），會於 `onload` 或 `onerror` 事件處理器之後才執行。

`FileReader.onprogress`

`progress` (en-US) 事件處理器，於讀取 `Blob` 內容時觸發。

**備註：** `FileReader` 物件繼承自 `EventTarget`，其所有的事件也都能夠透過 `addEventListener` 方法來註冊事件監聽器。

方法
--

`FileReader.abort()` (en-US)

中斷目前的讀取，此方法回傳後屬性 `readyState` 將會是 `DONE`。

`FileReader.readAsArrayBuffer()` (en-US)

開始讀取指定的 `Blob`，讀取完成後屬性 `result` 將以 `ArrayBuffer` 物件來表示讀入的資料內容。

`FileReader.readAsBinaryString()` (en-US)
非標準

開始讀取指定的 `Blob`，讀取完成後屬性 `result` 將以字串型式來表示讀入的原始二進位資料（raw binary data）。

`FileReader.readAsDataURL()` (en-US)

開始讀取指定的 `Blob`，讀取完成後屬性 `result` 將以 `data:` URL 格式（base64 編碼）的字串來表示讀入的資料內容。

`FileReader.readAsText()` (en-US)

開始讀取指定的 `Blob`，讀取完成後屬性 `result` 將以文字字串型式來表示讀入的資料內容。

規範
--

| Specification |
| --- |
| File API # APIASynch |

瀏覽器相容性
------

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

參見
--

* 在網頁應用程式中使用本地檔案
* `File`
* `Blob`


Vibration API - Web APIs

Vibration API
=============

目前大多數的行動裝置均具備振動硬體以搖晃裝置，讓軟體程式碼能對使用者產生實際反饋。**Vibration API** 即可讓 Web Apps 存取振動硬體。當然，若裝置並未支援振動硬體，就不會產生任何效果。

振動說明
----

振動即如「on-off」脈衝的形式，且持續時間亦有不同的變化。可透過單一整數讓振動持續數個毫秒 (ms)；或可由多個整數組成陣列，達到振動與暫停交錯的振動形式。只要單一 `window.navigator.vibrate()` (en-US) 函式即可控制振動。

### 單次振動

你可指定單一數值，或用單一數值構成 1 組陣列，讓振動硬體動作 1 次：

```js
window.navigator.vibrate(200);
window.navigator.vibrate([200]);
```

上列 2 個範例均可使裝置振動達 200 ms。

### 振動形式

用數值構成陣列，敘述裝置在一段期間內振動與停止振動的情形。陣列中的所有值均轉換為整數，接著直譯 (Interprete) 成裝置振動與停止振動的毫秒數。範例如下：

```js
window.navigator.vibrate([200, 100, 200]);
```

根據此陣列，裝置將振動 200 ms、暫停 100 ms，再振動 200 ms。

你可照自己喜好而指定多組振動/暫停的變化，且輸入項的數量為奇數或偶數均可。由於振動將在每個振動期間結束時停止，所以不一定要提供暫停數值作為最後 1 組輸入項。

### 取消目前振動

在 `window.navigator.vibrate()` (en-US) 的值為「0」、空白陣列，或陣列全為「0」時呼叫此函式，即可取消目前執行中的振動作業。`

規格
--

| Specification |
| --- |
| Vibration API (Second Edition) # dom-navigator-vibrate |

瀏覽器相容性
------

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

另可參閱
----

* `window.navigator.vibrate()`


setInterval() - Web APIs

setInterval()
=============

**`setInterval()`** 函式, `Window` (en-US) 與 `Worker` (en-US) 介面皆提供此一函式, 此函式作用為重複地執行一個函式呼叫或一個程式碼片斷, 每一次執行間隔固定的延遲時間. 此函式呼叫時將傳回一個間隔代碼(Interval ID)用以識別該間隔程序, 因此後續你可以呼叫 `clearInterval()` (en-US) 函式移除該間隔程序. 此函式為由 `WindowOrWorkerGlobalScope` 混合定義。

Syntax
------
```

var intervalID = scope.setInterval(func, [delay, arg1, arg2, ...]);
var intervalID = scope.setInterval(code, [delay]);
```

### Parameters

`func`

A `function` (en-US) to be executed every `delay` milliseconds. The function is not passed any arguments, and no return value is expected.

`code`

An optional syntax allows you to include a string instead of a function, which is compiled and executed every `delay` milliseconds. This syntax is *not recommended* for the same reasons that make using `eval()` (en-US) a security risk.

`delay`選擇性

The time, in milliseconds (thousandths of a second), the timer should delay in between executions of the specified function or code. See Delay restrictions below for details on the permitted range of `delay` values.

`arg1, ..., argN` 選擇性

Additional arguments which are passed through to the function specified by *func* once the timer expires.

**備註：** Passing additional arguments to `setInterval()` in the first syntax does not work in Internet Explorer 9 and earlier. If you want to enable this functionality on that browser, you must use a polyfill (see the Callback arguments section).

### Return value

The returned `intervalID` is a numeric, non-zero value which identifies the timer created by the call to `setInterval()`; this value can be passed to `clearInterval()` (en-US) to cancel the timeout.

It may be helpful to be aware that `setInterval()` and `setTimeout()` (en-US) share the same pool of IDs, and that `clearInterval()` and `clearTimeout()` (en-US) can technically be used interchangeably. For clarity, however, you should try to always match them to avoid confusion when maintaining your code.

**備註：** The `delay` argument is converted to a signed 32-bit integer. This effectively limits `delay` to 2147483647 ms, since it's specified as a signed integer in the IDL.

Examples
--------

### Example 1: Basic syntax

The following example demonstrates `setInterval()`'s basic syntax.

```js
var intervalID = window.setInterval(
  myCallback,
  500,
  "Parameter 1",
  "Parameter 2",
);

function myCallback(a, b) {
  // Your code here
  // Parameters are purely optional.
  console.log(a);
  console.log(b);
}
```

### Example 2: Alternating two colors

The following example calls the `flashtext()` function once a second until the Stop button is pressed.

```html
<!doctype html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>setInterval/clearInterval example</title>

    <script>
 var nIntervId;

 function changeColor() {
 nIntervId = setInterval(flashText, 1000);
 }

 function flashText() {
 var oElem = document.getElementById("my\_box");
 oElem.style.color = oElem.style.color == "red" ? "blue" : "red";
 // oElem.style.color == 'red' ? 'blue' : 'red' is a ternary operator.
 }

 function stopTextColor() {
 clearInterval(nIntervId);
 }
 </script>
  </head>

  <body onload="changeColor();">
    <div id="my\_box">
      <p>Hello World</p>
    </div>

    <button onclick="stopTextColor();">Stop</button>
  </body>
</html>
```

### Example 3: Typewriter simulation

The following example simulates typewriter by first clearing and then slowly typing content into the `NodeList` (en-US) that matches a specified group of selectors.

```html
<!doctype html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>JavaScript Typewriter - MDN Example</title>
    <script>
 function Typewriter(sSelector, nRate) {
 function clean() {
 clearInterval(nIntervId);
 bTyping = false;
 bStart = true;
 oCurrent = null;
 aSheets.length = nIdx = 0;
 }

 function scroll(oSheet, nPos, bEraseAndStop) {
 if (!oSheet.hasOwnProperty("parts") || aMap.length < nPos) {
 return true;
 }

 var oRel,
 bExit = false;

 if (aMap.length === nPos) {
 aMap.push(0);
 }

 while (aMap[nPos] < oSheet.parts.length) {
 oRel = oSheet.parts[aMap[nPos]];

 scroll(oRel, nPos + 1, bEraseAndStop)
 ? aMap[nPos]++
 : (bExit = true);

 if (
 bEraseAndStop &&
 ((oRel.ref.nodeType - 1) | 1) === 3 &&
 oRel.ref.nodeValue
 ) {
 bExit = true;
 oCurrent = oRel.ref;
 sPart = oCurrent.nodeValue;
 oCurrent.nodeValue = "";
 }

 oSheet.ref.appendChild(oRel.ref);
 if (bExit) {
 return false;
 }
 }

 aMap.length--;
 return true;
 }

 function typewrite() {
 if (
 sPart.length === 0 &&
 scroll(aSheets[nIdx], 0, true) &&
 nIdx++ === aSheets.length - 1
 ) {
 clean();
 return;
 }

 oCurrent.nodeValue += sPart.charAt(0);
 sPart = sPart.slice(1);
 }

 function Sheet(oNode) {
 this.ref = oNode;
 if (!oNode.hasChildNodes()) {
 return;
 }
 this.parts = Array.prototype.slice.call(oNode.childNodes);

 for (var nChild = 0; nChild < this.parts.length; nChild++) {
 oNode.removeChild(this.parts[nChild]);
 this.parts[nChild] = new Sheet(this.parts[nChild]);
 }
 }

 var nIntervId,
 oCurrent = null,
 bTyping = false,
 bStart = true,
 nIdx = 0,
 sPart = "",
 aSheets = [],
 aMap = [];

 this.rate = nRate || 100;

 this.play = function () {
 if (bTyping) {
 return;
 }
 if (bStart) {
 var aItems = document.querySelectorAll(sSelector);

 if (aItems.length === 0) {
 return;
 }
 for (var nItem = 0; nItem < aItems.length; nItem++) {
 aSheets.push(new Sheet(aItems[nItem]));
 /\* Uncomment the following line if you have previously hidden your elements via CSS: \*/
 // aItems[nItem].style.visibility = "visible";
 }

 bStart = false;
 }

 nIntervId = setInterval(typewrite, this.rate);
 bTyping = true;
 };

 this.pause = function () {
 clearInterval(nIntervId);
 bTyping = false;
 };

 this.terminate = function () {
 oCurrent.nodeValue += sPart;
 sPart = "";
 for (nIdx; nIdx < aSheets.length; scroll(aSheets[nIdx++], 0, false));
 clean();
 };
 }

 /\* usage: \*/
 var oTWExample1 = new Typewriter(
 /\* elements: \*/ "#article, h1, #info, #copyleft",
 /\* frame rate (optional): \*/ 15,
 );

 /\* default frame rate is 100: \*/
 var oTWExample2 = new Typewriter("#controls");

 /\* you can also change the frame rate value modifying the "rate" property; for example: \*/
 // oTWExample2.rate = 150;

 onload = function () {
 oTWExample1.play();
 oTWExample2.play();
 };
 </script>
    <style type="text/css">
 span.intLink,
 a,
 a:visited {
 cursor: pointer;
 color: #000000;
 text-decoration: underline;
 }

 #info {
 width: 180px;
 height: 150px;
 float: right;
 background-color: #eeeeff;
 padding: 4px;
 overflow: auto;
 font-size: 12px;
 margin: 4px;
 border-radius: 5px;
 /\* visibility: hidden; \*/
 }
 </style>
  </head>

  <body>
    <p
 id="copyleft"
 style="font-style: italic; font-size: 12px; text-align: center;">
      CopyLeft 2012 by
      <a href="https://developer.mozilla.org/" target="\_blank"
 >Mozilla Developer Network</a
 >
    </p>
    <p id="controls" style="text-align: center;">
      [ <span class="intLink" onclick="oTWExample1.play();">Play</span> |
      <span class="intLink" onclick="oTWExample1.pause();">Pause</span> |
      <span class="intLink" onclick="oTWExample1.terminate();">Terminate</span
 > ]
    </p>
    <div id="info">
      Vivamus blandit massa ut metus mattis in fringilla lectus imperdiet. Proin
      ac ante a felis ornare vehicula. Fusce pellentesque lacus vitae eros
      convallis ut mollis magna pellentesque. Pellentesque placerat enim at
      lacus ultricies vitae facilisis nisi fringilla. In tincidunt tincidunt
      tincidunt.
    </div>
    <h1>JavaScript Typewriter</h1>

    <div id="article">
      <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ultrices
        dolor ac dolor imperdiet ullamcorper. Suspendisse quam libero, luctus
        auctor mollis sed, malesuada condimentum magna. Quisque in ante tellus,
        in placerat est. Pellentesque habitant morbi tristique senectus et netus
        et malesuada fames ac turpis egestas. Donec a mi magna, quis mattis
        dolor. Etiam sit amet ligula quis urna auctor imperdiet nec faucibus
        ante. Mauris vel consectetur dolor. Nunc eget elit eget velit pulvinar
        fringilla consectetur aliquam purus. Curabitur convallis, justo posuere
        porta egestas, velit erat ornare tortor, non viverra justo diam eget
        arcu. Phasellus adipiscing fermentum nibh ac commodo. Nam turpis nunc,
        suscipit a hendrerit vitae, volutpat non ipsum.
      </p>
      <form>
        <p>
          Phasellus ac nisl lorem: <input type="text" /><br />
          <textarea style="width: 400px; height: 200px;">
Nullam commodo suscipit lacus non aliquet. Phasellus ac nisl lorem, sed facilisis ligula. Nam cursus lobortis placerat. Sed dui nisi, elementum eu sodales ac, placerat sit amet mauris. Pellentesque dapibus tellus ut ipsum aliquam eu auctor dui vehicula. Quisque ultrices laoreet erat, at ultrices tortor sodales non. Sed venenatis luctus magna, ultricies ultricies nunc fringilla eget. Praesent scelerisque urna vitae nibh tristique varius consequat neque luctus. Integer ornare, erat a porta tempus, velit justo fermentum elit, a fermentum metus nisi eu ipsum. Vivamus eget augue vel dui viverra adipiscing congue ut massa. Praesent vitae eros erat, pulvinar laoreet magna. Maecenas vestibulum mollis nunc in posuere. Pellentesque sit amet metus a turpis lobortis tempor eu vel tortor. Cras sodales eleifend interdum.</textarea
 >
        </p>
        <p><input type="submit" value="Send" /></p>
      </form>

      <p>
        Duis lobortis sapien quis nisl luctus porttitor. In tempor semper
        libero, eu tincidunt dolor eleifend sit amet. Ut nec velit in dolor
        tincidunt rhoncus non non diam. Morbi auctor ornare orci, non euismod
        felis gravida nec. Curabitur elementum nisi a eros rutrum nec blandit
        diam placerat. Aenean tincidunt risus ut nisi consectetur cursus. Ut
        vitae quam elit. Donec dignissim est in quam tempor consequat. Aliquam
        aliquam diam non felis convallis suscipit. Nulla facilisi. Donec lacus
        risus, dignissim et fringilla et, egestas vel eros. Duis malesuada
        accumsan dui, at fringilla mauris bibStartum quis. Cras adipiscing
        ultricies fermentum. Praesent bibStartum condimentum feugiat.
      </p>
      <p>
        Nam faucibus, ligula eu fringilla pulvinar, lectus tellus iaculis nunc,
        vitae scelerisque metus leo non metus. Proin mattis lobortis lobortis.
        Quisque accumsan faucibus erat, vel varius tortor ultricies ac. Lorem
        ipsum dolor sit amet, consectetur adipiscing elit. Sed nec libero nunc.
        Nullam tortor nunc, elementum a consectetur et, ultrices eu orci. Lorem
        ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque a nisl
        eu sem vehicula egestas.
      </p>
    </div>
  </body>
</html>
```

View this demo in action. See also: `clearInterval()` (en-US).

Callback arguments
------------------

As previously discussed, Internet Explorer versions 9 and below do not support the passing of arguments to the callback function in either `setTimeout()` or `setInterval()`. The following **IE-specific** code demonstrates a method for overcoming this limitation. To use, simply add the following code to the top of your script.

```js
/\*\
|\*|
|\*| IE-specific polyfill that enables the passage of arbitrary arguments to the
|\*| callback functions of javascript timers (HTML5 standard syntax).
|\*|
|\*| https://developer.mozilla.org/zh-TW/docs/Web/API/window.setInterval
|\*| https://developer.mozilla.org/User:fusionchess
|\*|
|\*| Syntax:
|\*| var timeoutID = window.setTimeout(func, delay[, arg1, arg2, ...]);
|\*| var timeoutID = window.setTimeout(code, delay);
|\*| var intervalID = window.setInterval(func, delay[, arg1, arg2, ...]);
|\*| var intervalID = window.setInterval(code, delay);
|\*|
\\*/

if (document.all && !window.setTimeout.isPolyfill) {
  var __nativeST__ = window.setTimeout;
  window.setTimeout = function (
    vCallback,
    nDelay /\*, argumentToPass1, argumentToPass2, etc. \*/,
  ) {
    var aArgs = Array.prototype.slice.call(arguments, 2);
    return \_\_nativeST\_\_(
      vCallback instanceof Function
        ? function () {
            vCallback.apply(null, aArgs);
          }
        : vCallback,
      nDelay,
    );
  };
  window.setTimeout.isPolyfill = true;
}

if (document.all && !window.setInterval.isPolyfill) {
  var __nativeSI__ = window.setInterval;
  window.setInterval = function (
    vCallback,
    nDelay /\*, argumentToPass1, argumentToPass2, etc. \*/,
  ) {
    var aArgs = Array.prototype.slice.call(arguments, 2);
    return \_\_nativeSI\_\_(
      vCallback instanceof Function
        ? function () {
            vCallback.apply(null, aArgs);
          }
        : vCallback,
      nDelay,
    );
  };
  window.setInterval.isPolyfill = true;
}
```

Another possibility is to use an anonymous function to call your callback, although this solution is a bit more expensive. Example:

```js
var intervalID = setInterval(function () {
  myFunc("one", "two", "three");
}, 1000);
```

Another possibility is to use function's bind. Example:

```js
var intervalID = setInterval(function (arg1) {}.bind(undefined, 10), 1000);
```

### Inactive tabs

Starting in Gecko 5.0, intervals are clamped to fire no more often than once per second in inactive tabs.

The "`this`" problem
--------------------

When you pass a method to `setInterval()` or any other function, it is invoked with the wrong `this` value. This problem is explained in detail in the JavaScript reference.

### Explanation

Code executed by `setInterval()` runs in a separate execution context than the function from which it was called. As a consequence, the `this` keyword for the called function is set to the `window` (or `global`) object, it is not the same as the `this` value for the function that called `setTimeout`. See the following example (which uses `setTimeout()` instead of `setInterval()` – the problem, in fact, is the same for both timers):

```js
myArray = ["zero", "one", "two"];

myArray.myMethod = function (sProperty) {
  alert(arguments.length > 0 ? this[sProperty] : this);
};

myArray.myMethod(); // prints "zero,one,two"
myArray.myMethod(1); // prints "one"
setTimeout(myArray.myMethod, 1000); // prints "[object Window]" after 1 second
setTimeout(myArray.myMethod, 1500, "1"); // prints "undefined" after 1,5 seconds
// passing the 'this' object with .call won't work
// because this will change the value of this inside setTimeout itself
// while we want to change the value of this inside myArray.myMethod
// in fact, it will be an error because setTimeout code expects this to be the window object:
setTimeout.call(myArray, myArray.myMethod, 2000); // error: "NS\_ERROR\_XPC\_BAD\_OP\_ON\_WN\_PROTO: Illegal operation on WrappedNative prototype object"
setTimeout.call(myArray, myArray.myMethod, 2500, 2); // same error
```

As you can see there are no ways to pass the `this` object to the callback function in the legacy JavaScript.

### A possible solution

A possible way to solve the "`this`" problem is to replace the two native `setTimeout()` or `setInterval()` global functions with two *non-native* ones that enable their invocation through the `Function.prototype.call` (en-US) method. The following example shows a possible replacement:

```js
// Enable the passage of the 'this' object through the JavaScript timers

var __nativeST__ = window.setTimeout,
  __nativeSI__ = window.setInterval;

window.setTimeout = function (
  vCallback,
  nDelay /\*, argumentToPass1, argumentToPass2, etc. \*/,
) {
  var oThis = this,
    aArgs = Array.prototype.slice.call(arguments, 2);
  return \_\_nativeST\_\_(
    vCallback instanceof Function
      ? function () {
          vCallback.apply(oThis, aArgs);
        }
      : vCallback,
    nDelay,
  );
};

window.setInterval = function (
  vCallback,
  nDelay /\*, argumentToPass1, argumentToPass2, etc. \*/,
) {
  var oThis = this,
    aArgs = Array.prototype.slice.call(arguments, 2);
  return \_\_nativeSI\_\_(
    vCallback instanceof Function
      ? function () {
          vCallback.apply(oThis, aArgs);
        }
      : vCallback,
    nDelay,
  );
};
```

**備註：** These two replacements also enable the HTML5 standard passage of arbitrary arguments to the callback functions of timers in IE. So they can be used as *non-standard-compliant* polyfills also. See the callback arguments paragraph for a *standard-compliant* polyfill.

New feature test:

```js
myArray = ["zero", "one", "two"];

myArray.myMethod = function (sProperty) {
  alert(arguments.length > 0 ? this[sProperty] : this);
};

setTimeout(alert, 1500, "Hello world!"); // the standard use of setTimeout and setInterval is preserved, but...
setTimeout.call(myArray, myArray.myMethod, 2000); // prints "zero,one,two" after 2 seconds
setTimeout.call(myArray, myArray.myMethod, 2500, 2); // prints "two" after 2,5 seconds
```

Another, more complex, solution for **the `this` problem** is the following framework.

**備註：** JavaScript 1.8.5 introduces the `Function.prototype.bind()` method, which lets you specify the value that should be used as `this` for all calls to a given function. This lets you easily bypass problems where it's unclear what this will be, depending on the context from which your function was called. Also, ES2015 supports arrow functions, with lexical this allowing us to write setInterval( () => this.myMethod) if we're inside myArray method.

MiniDaemon - A framework for managing timers
--------------------------------------------

In pages requiring many timers, it can often be difficult to keep track of all of the running timer events. One approach to solving this problem is to store information about the state of a timer in an object. Following is a minimal example of such an abstraction. The constructor architecture explicitly avoids the use of closures. It also offers an alternative way to pass the `this` object to the callback function (see The "this" problem for details). The following code is also available on GitHub.

**備註：** For a more complex but still modular version of it (`Daemon`) see JavaScript Daemons Management. This more complex version is nothing but a big and scalable collection of methods for the `Daemon` constructor. However, the `Daemon` constructor itself is nothing but a clone of `MiniDaemon` with an added support for *init* and *onstart* functions declarable during the instantiation of the `daemon`. **So the `MiniDaemon` framework remains the recommended way for simple animations**, because `Daemon` without its collection of methods is essentially a clone of it.

### minidaemon.js

```js
/\*\
|\*|
|\*| :: MiniDaemon ::
|\*|
|\*| Revision #2 - September 26, 2014
|\*|
|\*| https://developer.mozilla.org/zh-TW/docs/Web/API/window.setInterval
|\*| https://developer.mozilla.org/User:fusionchess
|\*| https://github.com/madmurphy/minidaemon.js
|\*|
|\*| This framework is released under the GNU Lesser General Public License, version 3 or later.
|\*| http://www.gnu.org/licenses/lgpl-3.0.html
|\*|
\\*/

function MiniDaemon(oOwner, fTask, nRate, nLen) {
  if (!(this && this instanceof MiniDaemon)) {
    return;
  }
  if (arguments.length < 2) {
    throw new TypeError("MiniDaemon - not enough arguments");
  }
  if (oOwner) {
    this.owner = oOwner;
  }
  this.task = fTask;
  if (isFinite(nRate) && nRate > 0) {
    this.rate = Math.floor(nRate);
  }
  if (nLen > 0) {
    this.length = Math.floor(nLen);
  }
}

MiniDaemon.prototype.owner = null;
MiniDaemon.prototype.task = null;
MiniDaemon.prototype.rate = 100;
MiniDaemon.prototype.length = Infinity;

/\* These properties should be read-only \*/

MiniDaemon.prototype.SESSION = -1;
MiniDaemon.prototype.INDEX = 0;
MiniDaemon.prototype.PAUSED = true;
MiniDaemon.prototype.BACKW = true;

/\* Global methods \*/

MiniDaemon.forceCall = function (oDmn) {
  oDmn.INDEX += oDmn.BACKW ? -1 : 1;
  if (
    oDmn.task.call(oDmn.owner, oDmn.INDEX, oDmn.length, oDmn.BACKW) === false ||
    oDmn.isAtEnd()
  ) {
    oDmn.pause();
    return false;
  }
  return true;
};

/\* Instances methods \*/

MiniDaemon.prototype.isAtEnd = function () {
  return this.BACKW
    ? isFinite(this.length) && this.INDEX < 1
    : this.INDEX + 1 > this.length;
};

MiniDaemon.prototype.synchronize = function () {
  if (this.PAUSED) {
    return;
  }
  clearInterval(this.SESSION);
  this.SESSION = setInterval(MiniDaemon.forceCall, this.rate, this);
};

MiniDaemon.prototype.pause = function () {
  clearInterval(this.SESSION);
  this.PAUSED = true;
};

MiniDaemon.prototype.start = function (bReverse) {
  var bBackw = Boolean(bReverse);
  if (this.BACKW === bBackw && (this.isAtEnd() || !this.PAUSED)) {
    return;
  }
  this.BACKW = bBackw;
  this.PAUSED = false;
  this.synchronize();
};
```

**備註：** MiniDaemon passes arguments to the callback function. If you want to work on it with browsers that natively do not support this feature, use one of the methods proposed above.

### Syntax
```

var myDaemon = new MiniDaemon(thisObject, callback[, rate[, length]]);
```

### Description

Returns a JavaScript `Object` (en-US) containing all information needed by an animation (like the `this` object, the callback function, the length, the frame-rate).

#### Arguments

`thisObject`

The `this` object on which the *callback* function is called. It can be an `object` (en-US) or `null`.

`callback`

The function that is repeatedly invoked . **It is called with three arguments**: *index* (the iterative index of each invocation), *length* (the number of total invocations assigned to the *daemon* - finite or `Infinity` (en-US)) and *backwards* (a boolean expressing whether the *index* is increasing or decreasing). It is something like *callback*.call(*thisObject*, *index*, *length*, *backwards*). **If the callback function returns a `false` value the *daemon* is paused**.

`rate (optional)`

The time lapse (in number of milliseconds) between each invocation. The default value is 100.

`length (optional)`

The total number of invocations. It can be a positive integer or `Infinity`. The default value is `Infinity`.

#### `MiniDaemon` instances properties

`myDaemon.owner`

The `this` object on which is executed the daemon (read/write). It can be an `object` (en-US) or `null`.

`myDaemon.task`

The function that is repeatedly invoked (read/write). It is called with three arguments: *index* (the iterative index of each invocation), *length* (the number of total invocations assigned to the daemon - finite or `Infinity` (en-US)) and backwards (a boolean expressing whether the *index* is decreasing or not) – see above. If the `myDaemon.task` function returns a `false` value the *daemon* is paused.

`myDaemon.rate`

The time lapse (in number of milliseconds) between each invocation (read/write).

`myDaemon.length`

The total number of invocations. It can be a positive integer or `Infinity` (read/write).

#### `MiniDaemon` instances methods

`myDaemon.isAtEnd()`

Returns a boolean expressing whether the *daemon* is at the start/end position or not.

`myDaemon.synchronize()`

Synchronize the timer of a started daemon with the time of its invocation.

`myDaemon.pause()`

Pauses the daemon.

`myDaemon.start([reverse])`

Starts the daemon forward (*index* of each invocation increasing) or backwards (*index* decreasing).

#### `MiniDaemon` global object methods

`MiniDaemon.forceCall(minidaemon)`

Forces a single callback to the `minidaemon.task` function regardless of the fact that the end has been reached or not. In any case the internal `INDEX` property is increased/decreased (depending on the actual direction of the process).

### Example usage

Your HTML page:

```html
<!doctype html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>MiniDaemin Example - MDN</title>
    <script type="text/javascript" src="minidaemon.js"></script>
    <style type="text/css">
 #sample\_div {
 visibility: hidden;
 }
 </style>
  </head>

  <body>
    <p>
      <input
 type="button"
 onclick="fadeInOut.start(false /\* optional \*/);"
 value="fade in" />
      <input type="button" onclick="fadeInOut.start(true);" value="fade out" />
      <input type="button" onclick="fadeInOut.pause();" value="pause" />
    </p>

    <div id="sample\_div">Some text here</div>

    <script type="text/javascript">
 function opacity(nIndex, nLength, bBackwards) {
 this.style.opacity = nIndex / nLength;
 if (bBackwards ? nIndex === 0 : nIndex === 1) {
 this.style.visibility = bBackwards ? "hidden" : "visible";
 }
 }

 var fadeInOut = new MiniDaemon(
 document.getElementById("sample\_div"),
 opacity,
 300,
 8,
 );
 </script>
  </body>
</html>
```

View this example in action

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

The `setInterval()` function is commonly used to set a delay for functions that are executed again and again, such as animations. You can cancel the interval using `clearInterval()` (en-US).

If you wish to have your function called *once* after the specified delay, use `setTimeout()` (en-US).

### Delay restrictions

It's possible for intervals to be nested; that is, the callback for `setInterval()` can in turn call `setInterval()` to start another interval running, even though the first one is still going. To mitigate the potential impact this can have on performance, once intervals are nested beyond five levels deep, the browser will automatically enforce a 4 ms minimum value for the interval. Attempts to specify a value less than 4 ms in deeply-nested calls to `setInterval()` will be pinned to 4 ms.

Browsers may enforce even more stringent minimum values for the interval under some circumstances, although these should not be common. Note also that the actual amount of time that elapses between calls to the callback may be longer than the given `delay`; see Reasons for delays longer than specified (en-US) for examples.

### Ensure that execution duration is shorter than interval frequency

If there is a possibility that your logic could take longer to execute than the interval time, it is recommended that you recursively call a named function using `setTimeout()` (en-US). For example, if using `setInterval()` to poll a remote server every 5 seconds, network latency, an unresponsive server, and a host of other issues could prevent the request from completing in its allotted time. As such, you may find yourself with queued up XHR requests that won't necessarily return in order.

In these cases, a recursive `setTimeout()` pattern is preferred:

```js
(function loop() {
  setTimeout(function () {
    // Your logic here

    loop();
  }, delay);
})();
```

In the above snippet, a named function `loop()` is declared and is immediately executed. `loop()` is recursively called inside `setTimeout()` after the logic has completed executing. While this pattern does not guarantee execution on a fixed interval, it does guarantee that the previous interval has completed before recursing.

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

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

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

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

See also
--------

* JavaScript timers
* `setTimeout` (en-US)
* `clearTimeout` (en-US)
* `clearInterval` (en-US)
* `window.requestAnimationFrame`
* *Daemons* management


WebSocket - Web APIs

WebSocket
=========

**實驗性質:** **這是一個實驗中的功能 (en-US)**
此功能在某些瀏覽器尚在開發中，請參考兼容表格以得到不同瀏覽器用的前輟。

`WebSocket` 物件提供了建立、管理 WebSocket 伺服器連線的 API，它也有在連線中傳送、接收資料的能力。

方法一覽
----

| `void close(in optional unsigned long code, in optional DOMString reason);` |
| --- |
| `void send(in DOMString data);` |

屬性
--

| 屬性 | 形態 | 描述 |
| --- | --- | --- |
| `binaryType` | `DOMString` | 表示連線傳輸的二進制資料形態的字串，若使用 `Blob` 物件則為 "blob"，使用 `ArrayBuffer` 物件則為 "arraybuffer"。 |
| `bufferedAmount` | `unsigned long` | 呼叫 `send()` 隊列但尚未傳輸至網路上資料的位元數。連線關閉時此值不會重設為零。連續呼叫 `send()` 會讓此值不斷上升。**唯讀** |
| `extensions` | `DOMString` | 伺服器選擇的擴展。目前僅有空字串或表示資料經過壓縮的 "deflate-stream"。**唯讀** |
| `onclose` | `EventListener` | 當 WebSocket 連線的 `readyState` 切換至 `CLOSED` 時呼叫的事件監聽器。監聽器接收命名為 "close" 的 `CloseEvent`。 |
| `onerror` | `EventListener` | 當錯誤發生時呼叫的事件監聽器。事件為命名 "error" 的簡單事件。 |
| `onmessage` | `EventListener` | 當瀏覽器接收伺服器的訊息時呼叫的事件監聽器。監聽器接收命名為 "message" 的 `MessageEvent`。 |
| `onopen` | `EventListener` | 當 WebSocket 連線的 `readyState` 切換至 `OPEN` 時呼叫的事件監聽器，表示連線已準備傳送、接收資料。事件為命名 "open" 的簡單事件。 |
| `protocol` | `DOMString` | 伺服器選擇的子協定，這是建立 WebSocket 物件時 `protocols` 參數裡的其中一個字串。 |
| `readyState` | `unsigned short` | 連線的目前狀態，是就緒狀態常數的其中一個。**唯讀** |
| `url` | `DOMString` | 建構方法解析出來的 URL，總是絕對 URL。**唯讀** |

常數
--

### 就緒狀態常數

`readyState` 屬性使用以下常數描述 WebSocket 的連線狀態。

| 常數 | 值 | 描述 |
| --- | --- | --- |
| `CONNECTING` | `0` | 連線尚未打開。 |
| `OPEN` | `1` | 連線已打開，可以進行通訊。 |
| `CLOSING` | `2` | 連線正在進行關閉程序。 |
| `CLOSED` | `3` | 連線已關閉／連線不能打開。 |

方法
--

### close()

關閉 WebSocket 連線／連線嘗試，若連線已為 `CLOSED`，此方法沒有作用。
```

void close(
  in optional unsigned short code,
  in optional DOMString reason
);
```

#### 參數

`code` 選擇性

表示狀態代碼，狀態代碼用以解釋連線關閉的原因。若未指定參數，預設值為 1000（表示正常的「事務完結（transaction complete）」關閉）。請參考 `CloseEvent` 頁面的狀態代碼列表，有所有的合法值。

`reason` 選擇性

解釋連線關閉原因的人類可讀字串，字串必不可大於 123 個 UTF-8 字符。

#### 可丟例外

`INVALID_ACCESS_ERR`

指定不合法的 `code`。

`SYNTAX_ERR`

`reason` 字串太長或是含有未配對的代理對。

### send()

透過 WebSocket 連線傳輸資料至伺服器。
```

void send(
  in DOMString data
);

void send(
  in ArrayBuffer data
);

void send(
  in Blob data
);
```

#### 參數

`data`

要傳送至伺服器的字串。

#### 可丟例外

`INVALID_STATE_ERR`

目前連線不為 `OPEN`。

`SYNTAX_ERR`

資料為帶有未配對代理對的字串。

#### 註釋

**備註：** Gecko `send()` 方法的實作與 Gecko 6.0 的規範有差別。Gecko 回傳一個 `boolean` 以表示連線是否仍處於開啟狀態（且資料成功隊列／傳輸）。另外，此時此刻，Gecko 不支援 `ArrayBuffer` 或 `Blob` 作為資料形態。

參見
--

* 製作 WebSocket 客戶端應用程式
* HTML5: WebSockets
瀏覽器兼容
-----

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


CloseEvent - Web APIs

CloseEvent
==========

當 WebSocket 連線關閉時，客戶端會收到一個 `CloseEvent`，由 `WebSocket` 物件 `onclose` 屬性表示的監聽器接收。

屬性
--

| 屬性 | 形態 | 描述 |
| --- | --- | --- |
| `code` | `unsigned long` | WebSocket 伺服器給予的連線關閉代碼。「狀態代碼」列有所有可能值。 |
| `reason` | `DOMString` | 表示伺服器關閉連線的原因，這因不同的伺服器與子協定而定。 |
| `wasClean` | `boolean` | 表示連線關閉情況是否乾淨。 |

狀態代碼
----

以下列有所有合法的狀態代碼。

| 狀態代碼 | 描述 |
| --- | --- |
| 0-999 | **尚未使用的保留值。** |
| 1000 | 正常關閉，連線成功地達到建立時的目標。 |
| 1001 | 端點去離，伺服器故障或是瀏覽器從開啟連線的頁面離去的情形。 |
| 1002 | 因協定錯誤造成連線被端點消滅。 |
| 1003 | 因端點接收不能處理的資料形態（舉例來說，文字端點收到二進制資料）而消滅連線。 |
| 1004 | 端點收到過大的資料幀而消滅連線。 |
| 1005 | **保留值**。表示意外地未給予狀態代碼的情形。 |
| 1006 | **保留值**。用以表示在預期收到狀態代碼的情形下不正常（即未送關閉幀）的連線關閉。 |
| 1007-1999 | **保留以作為未來的 WebSocket 標準之用。** |
| 2000-2999 | **保留以作為 WebSocket 擴展之用。** |
| 3000-3999 | 程式庫與框架使用的值，應用程式**可不**使用。 |
| 4000-4999 | 應用程式使用的值。 |

參見
--

* `WebSocket`
瀏覽器兼容
-----

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


FileSystem - Web APIs

FileSystem
==========

**非標準:** This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future.

**`FileSystem`** 實作文件和目錄介面，描述一個檔案系統。在任何檔案系統上，這個物件包含 `filesystem` (en-US)的特性。某些網頁瀏覽器提供額外的 API 去創建和管理檔案系統，如 Google Chrome 的`requestFileSystem()`函式。

**備註：** 此介面並非標準 API, 代表規格並未依造標準制定, 因此必須注意並非所有網頁瀏覽器都有實作此介面, 有實作的網頁瀏覽器可能只有實作一小部分. 請在Browser compatibility 查看更多細節.

基礎概念
----

存取 `FileSystem` 物件的兩種方法:

1. 你可以直接要求一個使用`window.requestFileSystem()，`只用在你的網頁應用程式的沙盒類型 `FileSystem 物件。如果要求成功，將會執行`callback handler 去接收描述檔案系統的`FileSystem物件參數。`
2. 你可以從檔案系統接口物件取得，透過他的`filesystem` (en-US)特性
屬性
--

`FileSystem.name` (en-US) Read only

`USVString` (en-US) 代表檔案系統的名稱. 此名稱在整個已宣告的檔案系統清單中是唯一的。

`FileSystem.root` (en-US) Read only

`FileSystemDirectoryEntry` (en-US) 物件表示檔案系統的根目錄。 透過此物件, 你可以取得權限存取所有檔案系統中的文件和目錄

規範
--

| Specification |
| --- |
| File and Directory Entries API # api-domfilesystem |

This API has no official W3C or WHATWG specification.

瀏覽器相容性
------

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

參見
--

* File and Directory Entries API
* Introduction to the File System API (en-US)
* `FileSystemEntry` (en-US), `FileSystemFileEntry` (en-US), and `FileSystemDirectoryEntry` (en-US)
* MSDN 文章: WebKitFileSystem object


HTML 拖放 API - Web APIs

HTML 拖放 API
===========

HTML 拖放介面能讓網頁應用程式於 Firefox 及其他瀏覽器中使用拖放功能。舉例來說，使用者可以利用此功能以滑鼠選擇\*可拖曳（draggable）*元素，拖曳至一個*可放置（droppable）*元素上，並放開滑鼠按鍵來放置此元素。在拖曳操作時，一個半透明的*可拖曳（draggable）\*元素會跟隨著滑鼠游標。

對於網站、擴充套件以及 XUL 應用程式來說，你可以自定義能成為\*可拖曳（draggable）\*的元素類型、\*可拖曳（draggable）*元素產生的回鐀類型，以及*可放置（droppable）\*的元素。

此文件為 HTML 拖放的概述，包含了相關介面的說明、在應用程式中加入拖放支援的基本步驟，以及相關介面使用簡介。

拖曳事件
----

HTML 拖放操作基於 `DOM 事件模型`並且使用繼承自`滑鼠事件` (en-US)的\*`拖曳事件`*介面。一個典型的拖曳操作開始於使用者利用滑鼠選取了一個*可拖曳（draggable）*元素、移動滑鼠至一個*可放置（droppable）\*元素並放開滑鼠按鍵。在操作的過程中，會觸發多種類型的事件，且一些事件類型可能會被觸發多次（如 `drag` (en-US) 及 `dragover` (en-US) 事件類型）。

所有的拖曳事件類型都有相關的通用事件處理器（global event handler）。每一種拖曳事件類型及拖曳通用事件處理器屬性都有說明此事件的參考文件。以下的表格提供了每一種事件的簡要說明，以及參考文件的連結。

| 事件 | 事件處理器屬性 | 說明 |
| --- | --- | --- |
| `drag` (en-US) | `ondrag` (en-US) | 於一個元素或文字選取區塊被拖曳時觸發。 |
| `dragend` (en-US) | `ondragend` (en-US) | 於拖曳操作結束時觸發（如放開滑鼠按鍵或按下鍵盤的 escape 鍵）。（請參考結束拖曳 (en-US)。） |
| `dragenter` (en-US) | `ondragenter` (en-US) | 於一個元素或文字選取區塊被拖曳移動進入一個有效的放置目標時觸發。（請參考指定拖曳目標 (en-US)。） |
| `dragleave` (en-US) | `ondragleave` (en-US) | 於一個元素或文字選取區塊被拖曳移動離開一個有效的放置目標時觸發。 |
| `dragover` (en-US) | `ondragover` (en-US) | 於一個元素或文字選取區塊被拖曳移動經過一個有效的放置目標時觸發（每幾百毫秒觸發一次）。 |
| `dragstart` (en-US) | `ondragstart` (en-US) | 於使用者開始拖曳一個元素或文字選取區塊時觸發。（請參考開始拖曳 (en-US)。） |
| `drop` (en-US) | `ondrop` (en-US) | 於一個元素或文字選取區塊被放置至一個有效的放置目標時觸發。（請參考執行放置 (en-US)。） |

注意：`dragstart` 與 `dragend` 事件，在把檔案從作業系統拖放到瀏覽器時，並不會觸發。

介面
--

HTML 拖放介面有 `DragEvent`、`DataTransfer` (en-US)、`DataTransferItem` (en-US) 以及 `DataTransferItemList` (en-US)。

`DragEvent` 介面擁有一個建構式及一個屬性－`dataTransfer` 屬性為一個 `DataTransfer` (en-US) 物件。`DataTransfer` (en-US) 物件包含了拖放事件的狀態，如正在進行的拖放事件類型（例如 `copy` 或 `move`）、拖放中的資料（一或多個項目）以及每一個\*拖放項目（drag item）\*的檔案類型（MIME type）。`DataTransfer` (en-US) 物件也擁有加入及移除拖放資料項目的方法。`DragEvent` 與 `DataTransfer` (en-US) 介面應該是唯一須要加至應用程式中的 HTML 拖放功能。另外，請留意 Firefox 支援了一些 Gecko-specific 擴充予 `DataTransfer` (en-US) 物件使用，雖然這些擴充只能在 Firefox 上作用。

每個 `DataTransfer` (en-US) 物件都包含了 `items` (en-US) 屬性。此屬性乃 `DataTransferItem` (en-US) 物件的 `list` (en-US)。而每個 `DataTransferItem` (en-US) 物件，則代表著一個*拖放單元*，每個拖放單元則擁有代表該資料*種類*的 `kind` (en-US) 屬性（`string` 或 `file`）、還有表示該單元檔案類型（如 MIME）的`type` (en-US) 屬性。另外，`DataTransferItem` (en-US) 物件能取得拖放單元的資料。

`DataTransferItemList` (en-US) 物件為 `DataTransferItem` (en-US) 的列表。該物件列表擁有以下方法：給列表增加拖放單元、從列表刪除拖放單元、還有清除列表內所有的拖放單元。

`DataTransfer` (en-US) 與 `DataTransferItem` (en-US) 介面的最大不同，就是前者使用同步的 `getData()` (en-US) 方法訪問拖放單元的資料；後者則使用非同步的 `getAsString()` (en-US) 方法訪問。

注意：`DragEvent` 與 `DataTransfer` (en-US) 介面受廣泛的桌面瀏覽器支援。但只有少數瀏覽器支援 `DataTransferItem` (en-US) 與 `DataTransferItemList` (en-US) 介面。請參見 Interoperability 以取得有關拖放功能互通性的資訊。

### Gecko-specific interfaces

Mozilla and Firefox support some features not in the standard drag and drop model. These are *convenience functions* to facilitate dragging multiple items and dragging non-string data (such as files). For more information, see Dragging and Dropping Multiple Items. Additionally, see the `DataTransfer` (en-US) reference page for all of the Gecko-specific properties (en-US) and Gecko-specific methods (en-US).

基本用法
----

This section provides a summary of the basic steps to add drag and drop functionality to an application. Each section includes a description of the step, a short code example, and links to additional information.

### Identify what is *draggable*

To make an element *draggable* requires adding the `draggable` (en-US) attribute plus the `ondragstart` (en-US) global event handler, as shown in the following code sample

```js
function dragstart\_handler(ev) {
  console.log("dragStart");
  // Add the target element's id to the data transfer object
  ev.dataTransfer.setData("text/plain", ev.target.id);
}

<body>
  <p id="p1" draggable="true" ondragstart="dragstart\_handler(event);">
    This element is draggable.
  </p>
</body>;
```

See the draggable attribute reference (en-US) and the Drag operations guide for more information.

### Define the drag's data

The application is free to include any number of data items in a drag operation. Each data item is a `string` of a particular `type`, typically a MIME type such as `text/html`.

Each `drag event` has a `dataTransfer` property that *holds* the event's data. This property (which is a `DataTransfer` (en-US) object) also has methods to *manage* drag data. The `setData()` (en-US) method is used to add an item to the drag data, as shown in the following example.

```js
function dragstart\_handler(ev) {
  // Add the drag data
  ev.dataTransfer.setData("text/plain", ev.target.id);
  ev.dataTransfer.setData("text/html", "<p>Example paragraph</p>");
  ev.dataTransfer.setData("text/uri-list", "http://developer.mozilla.org");
}
```

For a list of common data types used for drag and drop (such as text, HTML, links, and files), see Recommended Drag Types (en-US) and for more information about drag data, see Drag Data.

### Define the drag image

By default, the browser supplies an image that appears beside the mouse pointer during a drag operation. However, an application may define a custom image by using the `setDragImage()` (en-US) method as shown in the following example.

```js
function dragstart\_handler(ev) {
  // Create an image and then use it for the drag image.
  // NOTE: change "example.gif" to an existing image or the image
  // will not be created and the default drag image will be used.
  var img = new Image();
  img.src = "example.gif";
  ev.dataTransfer.setDragImage(img, 10, 10);
}
```

To learn more about drag feedback images, see Setting the Drag Feedback Image (en-US).

### Define the drag *effect*

The `dropEffect` (en-US) property is used to control the feedback (typically visual) the user is given during a drag and drop operation. It affects which cursor the browser displays while dragging. For example, when the user hovers over a target drop element, the browser's cursor may indicate the type of operation that will occur.

Three effects may be defined:

`copy` indicates that the data being dragged will be copied from its present location to the drop location.

`move` indicates that the data being dragged will be moved

`link` indicates that some form of relationship or connection will be created between the source and drop locations.

During the drag operation, the drag effects may be modified to indicate that certain effects are allowed at certain locations. If allowed, a drop may occur at that location.

The following example shows how to use this property.

```js
function dragstart\_handler(ev) {
  // Set the drag effect to copy
  ev.dataTransfer.dropEffect = "copy";
}
```

See Drag Effects for more details.

### Define a *drop zone*

By default, the browser prevents anything from happening when dropping something onto the HTML element. To change that behavior so that an element becomes a *drop zone* or is *droppable*, the element must have both `ondragover` (en-US) and `ondrop` (en-US) event handler attributes. The following example shows how to use those attributes and includes basic event handlers for each attribute.

```js
function dragover\_handler(ev) {
  ev.preventDefault();
  // Set the dropEffect to move
  ev.dataTransfer.dropEffect = "move";
}
function drop\_handler(ev) {
  ev.preventDefault();
  // Get the id of the target and add the moved element to the target's DOM
  var data = ev.dataTransfer.getData("text");
  ev.target.appendChild(document.getElementById(data));
}
<body>
  <div
    id="target"
    ondrop="drop\_handler(event);"
    ondragover="dragover\_handler(event);">
    Drop Zone
  </div>
</body>;
```

Note each handler calls `preventDefault()` to prevent additional event processing for this prevent (such as touch events or pointer events).

For more information, see Specifying Drop Targets.

### Handle the drop *effect*

The handler for the `drop` (en-US) event is free to process the drag data in an application specific way. Typically, an application will use the `getData()` (en-US) method to retrieve drag items and process them accordingly. Additionally, application semantics may differ depending on the value of the `dropEffect` (en-US) and/or the state of modifier keys.

The following example shows a drop handler getting the source element's id from the drag data and then using the id to move the source element to the drop element.

```js
function dragstart\_handler(ev) {
  // Add the target element's id to the data transfer object
  ev.dataTransfer.setData("text/plain", ev.target.id);
  ev.dropEffect = "move";
}
function dragover\_handler(ev) {
  ev.preventDefault();
  // Set the dropEffect to move
  ev.dataTransfer.dropEffect = "move";
}
function drop\_handler(ev) {
  ev.preventDefault();
  // Get the id of the target and add the moved element to the target's DOM
  var data = ev.dataTransfer.getData("text");
  ev.target.appendChild(document.getElementById(data));
}
<body>
  <p id="p1" draggable="true" ondragstart="dragstart\_handler(event);">
    This element is draggable.
  </p>
  <div
    id="target"
    ondrop="drop\_handler(event);"
    ondragover="dragover\_handler(event);">
    Drop Zone
  </div>
</body>;
```

For more information, see Performing a Drop.

### Drag end

At the end of a drag operation, the `dragend` (en-US) event fires at the *source* element - the element that was the target of the drag start. This event fires whether the drag completed or was canceled. The `dragend` (en-US) event handler can check the value of the `dropEffect` (en-US) property to determine if the drag operation succeeded or not.

For more information about handling the end of a drag operation, see Finishing a Drag (en-US).

Interoperability
----------------

As can be seen in the DataTransferItem interface's Browser Compatibility table (en-US), drag-and-drop interoperability is relatively broad among desktop browsers (except the `DataTransferItem` (en-US) and `DataTransferItemList` (en-US) interfaces have less support). This data also indicates drag and drop support among mobile browsers is very low.

Examples and demos
------------------

* Copying and moving elements with the `DataTransfer` interface
* Copying and moving elements with the `DataTransferListItem` interface
* Dragging and dropping files; Firefox only: http://jsfiddle.net/9C2EF/
* Dragging and dropping files; All browsers: https://jsbin.com/hiqasek/
* A parking project using the Drag and Drop API: https://park.glitch.me/ (You can edit here)
規範
--

| Specification |
| --- |
| HTML Standard  |

參見
--

* Drag Operations
* Dragging and Dropping Multiple Items
* Recommended Drag Types (en-US)
* HTML5 Living Standard: Drag and Drop
* Drag and Drop interoperability data from CanIUse


GainNode - Web APIs

GainNode
========

`GainNode` 介面代表的是音量改變。 這是 `AudioNode` (en-US) 音訊處理模組，可以對輸入的訊號做增益 (gain) 後輸出。一個 `GainNode` 有一個輸入和一個輸出，兩者有相同的聲道數。

增益 (gain) 是無單位的數值，隨時間變化，會用來和所有輸入聲道的取樣做相乘。 如果更改的話，新的增益會用 de-zippering 演算法處理，以避免輸出聲音出現難聽的「喀」聲。

![The GainNode is increasing the gain of the output.](/zh-TW/docs/Web/API/GainNode/webaudiogainnode.png)

|  |  |
| --- | --- |
| Number of inputs | `1` |
| Number of outputs | `1` |
| Channel count mode | `"max"` |
| Channel count | `2` (not used in the default count mode) |
| Channel interpretation | `"speakers"` |

Constructor
-----------

`GainNode()` (en-US)

Creates a new instance of an GainNode object.

Properties
----------

*Inherits properties from its parent,* *`AudioNode` (en-US)*.

`GainNode.gain` Read only

是 a-rate (en-US) `AudioParam` (en-US) ，代表增益值

Methods
-------

*No specific method; inherits methods from its parent,* *`AudioNode` (en-US)*.

Example
-------

See `BaseAudioContext.createGain()` (en-US) for example code showing how to use an `AudioContext` to create a `GainNode`.

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

| Specification |
| --- |
| Web Audio API # GainNode |

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

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

See also
--------

* Using the Web Audio API (en-US)


UIEvent - Web APIs

UIEvent
=======

**`UIEvent`** 介面是使用者介面的事件的基本型態。

`UIEvent` 是從 `Event` 衍伸過來。 雖然為了相容性，仍留著 `UIEvent.initUIEvent()` (en-US) 方法，建立 `UIEvent` 物件最好是選擇以 `UIEvent()` constructor 建立。

許多介面直接或間接繼承此介面，例如：`MouseEvent` (en-US)、`TouchEvent` (en-US)、`FocusEvent` (en-US)、`KeyboardEvent`、`WheelEvent`、`InputEvent` (en-US) 和 `CompositionEvent` (en-US)。

建構式
---

`UIEvent()`

建立一個 `UIEvent` 物件 。

屬性
--

*此介面亦繼承其父－－ `Event` 的屬性：*

`UIEvent.cancelBubble` (en-US)
非標準

已棄用

Is a `Boolean` indicating whether the bubbling of the event has been canceled or not.

`UIEvent.detail` (en-US)Read only

Returns a `long` with details about the event, depending on the event type.

`UIEvent.isChar`
已棄用
 Read only

Returns a `Boolean` indicating whether the event produced a key character or not.

`UIEvent.layerX` (en-US)
非標準
 Read only

Returns the horizontal coordinate of the event relative to the current layer.

`UIEvent.layerY` (en-US)
非標準
 Read only

Returns the vertical coordinate of the event relative to the current layer.

`UIEvent.pageX` (en-US)
非標準
 Read only

Returns the horizontal coordinate of the event relative to the whole document.

`UIEvent.pageY` (en-US)
非標準
 Read only

Returns the vertical coordinate of the event relative to the whole document.

`UIEvent.sourceCapabilities` (en-US)
非標準
 Read only

Returns an instance of the InputDeviceCapabilities interface which provides information about the physical device responsible for generating a touch event.

`UIEvent.view` (en-US)Read only

Returns a `WindowProxy` that contains the view that generated the event.

`UIEvent.which` (en-US)
非標準
 Read only

Returns the numeric `keyCode` of the key pressed, or the character code (`charCode`) for an alphanumeric key pressed.

方法
--

*此介面亦繼承其父－－ `Event` 的方法：*

`UIEvent.initUIEvent()` (en-US)
已棄用

初始化 `UIEvent` 物件。若該事件已經觸發的話，此方法就不會執行任何東西。

規範
--

| Specification |
| --- |
| UI Events # idl-uievent |

瀏覽器相容性
------

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

參見
--

* Introduction to events (en-US)
* `Event`


Notification - Web APIs

Notification
============

Notifications API 的 `Notification` interface 是用來設置及顯示「桌面通知」給使用。

**備註：** 此功能可在 Web Worker (en-US) 中使用

Constructor
-----------

`Notification()` (en-US)

建立一個新的 `Notification` 實例。

Properties
----------

### 靜態屬性

以下的屬性僅適用於 `Notification` 實例。

`Notification.permission` (en-US) Read only

一個表示允許通知顯示與否的權限的 string。可能的值有：「denied」(使用者不允許顯示 Notification )、「granted」(使用者允許顯示 Notification )，或者是「default」(還不知道使用者允許與否，預設行為與 denied 一致)。

### 實例屬性

以下屬應僅適用於 `Notification` 實例。

`Notification.title` (en-US) Read only

在建構子的 options 參數中指定的 Notification 的標題。

`Notification.dir` (en-US) Read only

在建構子的 options 參數中指定的 Notification 的文字顯示方向。

`Notification.lang` (en-US) Read only

在建構子的 options 參數中指定的 Notification 的語言代號。

`Notification.body` (en-US) Read only

在建構子的 options 參數中指定的 Notification 的內容。

`Notification.tag` (en-US) Read only

The ID of the notification (if any) as specified in the options parameter of the constructor.

`Notification.icon` (en-US) Read only

在建構子的 options 參數中指定的 Notification 的 icon 的網址。

`Notification.data` (en-US) Read only

回傳結構化的 Notification 的資料。

`Notification.requireInteraction` (en-US) Read only

一個 `Boolean` 指示在有充足大小的螢幕上的時候，Notfication 實例是否會持續顯示直到使用者點擊它或者 dismisses it。

`Notification.silent` (en-US) Read only

表示 Notfication 是否設定要以較低調的方式呈現(比如不撥放通知音效、不震動)。這個設定與裝置本身的設定無關。

`Notification.timestamp` (en-US) Read only

表示 Notification 的建立時間、或者可啟動的時間 (可能是過去、現在或未來)。

`Notification.vibrate` (en-US) Read only

表示在可震動的裝置上的震動模式。

#### 尚未支援的屬性

The following properties are listed in the most up-to-date spec, but are not supported in any browsers yet. It is advisable to keep checking back regularly to see if the status of these has updated, and let us know if you find any out of date information.

`Notification.noscreen` Read only

表示 Notification 顯示時是否要打開裝置的螢幕。

`Notification.renotify` (en-US) Read only

表示使用者是否會在舊的 Notification 被新的 Notification 替換掉時通知。

`Notification.sound` Read only

表示當 Notification 顯示時要用來代替系統預設音效撥放的音訊資源。

`Notification.sticky` Read only

表示 Notification 是否「sticky」(比如使用者不太容易清除它)。

#### 事件處理器

`Notification.onclick` (en-US)

一個 `click` (en-US) 事件的 handler。每次使用者點擊 Notification 都會被觸發。

`Notification.onerror` (en-US)

一個 `error` (en-US) 事件的 handler. 每次 Notification 發生 Error 都會被觸發。

#### 停止支援的事件處理器

底下這些列在 瀏覽器支援度 中的 event handlers 雖然還有支援，但已經從近期的 spec 中移除了。因為瀏覽器會在未來的版本逐漸停止支援，最好還是不要使用它們。

`Notification.onclose` (en-US)

A handler for the `close` (en-US) event. It is triggered when the user closes the notification.

`Notification.onshow` (en-US)

A handler for the `show` event. It is triggered when the notification is displayed.

方法
--

### 靜態方法

這些方法只能在 `Notification` 實例上使用。

`Notification.requestPermission()` (en-US)

向使用者詢問是否開放顯示 Notification 的權限。

### 實例方法

These properties are available only on an instance of the `Notification` object or through its `prototype` (en-US). The `Notification` object also inherits from the `EventTarget` interface.

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

透過這個方法關閉 Notification 。

範例
--

先看這段基本的 HTML：

```html
<button onclick="notifyMe()">Notify me!</button>
```

用下面的程式碼我們可以送出通知： 底下的程式碼雖然略嫌冗長，但完整的示範了如何在送出通知之前，事先檢查了瀏覽器是否支援 Notification、使用者是否授權這個網域的網頁送出通知，以及在需要的時候向使用者詢問是否開放權限。

```js
function notifyMe() {
  // 首先讓我們確定瀏覽器支援 Notification
  if (!("Notification" in window)) {
    alert("這個瀏覽器不支援 Notification");
  }

  // 再檢查使用者是否已經授權執行 Notification
  else if (Notification.permission === "granted") {
    // 如果已經授權就可以直接新增 Notification 了!
    var notification = new Notification("安安你好!");
  }

  // 否則，我們會需要詢問使用者是否開放權限
  else if (Notification.permission !== "denied") {
    Notification.requestPermission(function (permission) {
      // 如果使用者同意了就來新增一個 Notification 打聲招呼吧
      if (permission === "granted") {
        var notification = new Notification("安安~");
      }
    });
  }

  // 如果使用者還是不同意授權執行 Notification
  // 最好還是進行適當的處理以避免繼續打擾使用者
}
```

在很多時候，你應該不會想要這麼冗長的程式碼。 比如說，在我們的 Emogotchi demo (see source code) 之中，我們只寫了 `Notification.requestPermission` (en-US) 而不用進一步檢查是否已經獲得了權限：

```js
Notification.requestPermission();
```

然後我們只需要在要新增 Notfication 時執行這個 `spawnNotification()` — 透過傳入指定的 body、icon、title，然後它就會產生我們所需的 options 參數並透過 `Notification()` (en-US) 建構子發送 Notification.

```js
function spawnNotification(theBody, theIcon, theTitle) {
  var options = {
    body: theBody,
    icon: theIcon,
  };
  var n = new Notification(theTitle, options);
}
```

規格
--

| Specification |
| --- |
| Notifications API Standard # api |

瀏覽器支援度
------

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

延伸閱讀
----

* Using the Notifications API


EventTarget - Web APIs

EventTarget
===========

**`EventTarget`** 介面定義了其實作的物件具有接收事件的能力，也可能擁有處理事件的監聽器。

除了最為常見的 `Element` (en-US)、`Document` (en-US) 與 `Window` (en-US) 繼承或實作了 `EventTarget` 介面之外，其它的物件還有 `XMLHttpRequest`、`AudioNode` (en-US)、`AudioContext` (en-US)⋯ 等等。

許多 `EventTarget`（包括 Element、Document 和 Window）除了透過 `addEventListener()` 方法外，還可藉由 `DOM` 物件的屬性（property）或 HTML 元素 (en-US)屬性（attribute）來設定事件處理器 (en-US)。

方法
--

`EventTarget.addEventListener()`

於 `EventTarget` 物件上註冊指定事件的監聽器。

`EventTarget.removeEventListener()` (en-US)

移除 `EventTarget` 物件上的指定事件監聽器。

`EventTarget.dispatchEvent()`

對此 `EventTarget` 物件派送（dispatch）一個事件物件，也就是於此 `EventTarget` 物件上觸發一個指定的事件物件實體。

### Mozilla chrome code 的額外方法

Mozilla extensions for use by JS-implemented event targets to implement on properties. See also WebIDL bindings.

* void **setEventHandler**(DOMString type, EventHandler handler)
非標準
* EventHandler **getEventHandler**(DOMString type)
非標準
範例
--

### Simple implementation of EventTarget

```js
var EventTarget = function () {
  this.listeners = {};
};

EventTarget.prototype.listeners = null;
EventTarget.prototype.addEventListener = function (type, callback) {
  if (!(type in this.listeners)) {
    this.listeners[type] = [];
  }
  this.listeners[type].push(callback);
};

EventTarget.prototype.removeEventListener = function (type, callback) {
  if (!(type in this.listeners)) {
    return;
  }
  var stack = this.listeners[type];
  for (var i = 0, l = stack.length; i < l; i++) {
    if (stack[i] === callback) {
      stack.splice(i, 1);
      return;
    }
  }
};

EventTarget.prototype.dispatchEvent = function (event) {
  if (!(event.type in this.listeners)) {
    return true;
  }
  var stack = this.listeners[event.type];
  event.target = this;
  for (var i = 0, l = stack.length; i < l; i++) {
    stack[i].call(this, event);
  }
  return !event.defaultPrevented;
};
```

規範
--

| Specification |
| --- |
| DOM Standard # interface-eventtarget |

瀏覽器相容性
------

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

參見
--

* Event reference - the events available in the platform.
* Event developer guide
* `Event` interface


FormData - Web APIs

FormData
========

**`FormData`** 介面可為表單資料中的欄位/值建立相對應的的鍵/值對（key/value）集合，之後便可使用 `XMLHttpRequest.send()` (en-US) 方法來送出資料。它在編碼類型設定為 `multipart/form-data` 時會採用與表單相同的格式送出。

實作 `FormData` 的物件可以直接利用 `for...of` (en-US) 語法結構來替代 `entries()` (en-US)：`for (var p of myFormData)` 等同於 `for (var p of myFormData.entries())`。

**備註：** 此特性適用於 Web Workers (en-US)。

建構式
---

`FormData()` (en-US)

建立一個新的 `FormData` 物件。

方法
--

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

追加新值到 `FormData` 物件已有的對應鍵上；若該鍵不存在，則為其追加新的鍵。

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

刪除指定的鍵值對。

`FormData.entries()` (en-US)

回傳 `iterator`，可用來處理物件中所有的鍵值對。

`FormData.get()`

回傳指定的鍵在 `FormData` 物件中找到的第一個對應值。

`FormData.getAll()` (en-US)

回傳指定的鍵在 `FormData` 物件中所有對應值的陣列。

`FormData.has()` (en-US)

回傳 `FormData` 物件是否含有指定鍵值對的布林值。

`FormData.keys()` (en-US)

回傳 `iterator`，可用來處理物件中所有鍵值對之中的鍵。

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

為 `FormData` 物件已有的鍵設定新值；若該鍵不存在，則為其追加新的鍵。

`FormData.values()` (en-US)

回傳 `iterator`，可用來處理物件中所有鍵值對之中的值。

規範
--

| Specification |
| --- |
| XMLHttpRequest Standard # interface-formdata |

瀏覽器相容性
------

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

參見
--

* `XMLHTTPRequest`
* 使用 XMLHttpRequest
* 使用 FormData 物件 (en-US)
* `<form>` (en-US)


權限 (Permissions) - Web APIs

權限 (Permissions)
================

摘要
--

Permissions API 可顯示 Apps 所要求的所有權限，以利使用者管理。Apps 可透過此 API 而讀取其他 Apps 的權限並進一步變更。

透過 `PermissionSettings` 介面的 `navigator.mozPermissionSettings` 屬性，即可存取 Permission Manager。

已安裝 Apps 的權限
------------

所有 Apps 均需透過自己的 manifest 檔案而要求權限。Apps 每次所使用的 API，均以「請求顯性權限 (Explicit Permission)」的 API 為主，並提示使用者是否通過權限。如果使用者選擇「不要再提示」，大概也就不太可能改變決定了。API 則能提供介面，以利使用者管理已發出的權限。

透過 `PermissionSettings.get()`、`set()`、`isExplicit()` 函式即可達到上述作業。

### 讀取權限

若要知道已發出權限的目前狀態，可使用 `PermissionSettings.get()` 函式。此函式可回傳字串，以顯示特定 Apps 權限的目前狀態。可能的數值有：

`allow`

已通過該權限，且不需使用者的進一步互動。

`denied`

已否決該權限；可能是系統或使用者所否決。

`prompt`

代表該權限將以明顯的提示方法，詢問使用者是否給予權限。

`unknown`

代表該 Apps 並未詢問此權限，也不會提示使用者是否給予權限。

```js
// Let's check all installed apps
var apps = navigator.mozApps.mgmt.getAll();

apps.onsuccess = function () {
  var permission = navigator.mozPermissionSettings;

  // Let's check the permission of each app
  apps.result.forEach(function (app) {
    var request,
      appName = app.manifest.name;

    for (request in app.manifest.permission) {
      // Let's get the current permission for each permission request by the application
      var p = permission.get(request, app.manifestUrl, app.origine, false);

      console.log(
        appName +
          ' asked for "' +
          request +
          '" permission, which is "' +
          p +
          '"',
      );
    }
  });
};
```

### 設定權限

只要使用 `PermissionSettings.set()` 函式即可設定權限。可能的數值均與 `get` 函式所存取的相同。

**備註：** 根據 Apps 權限的不同，某些可能為隱性 (Implicit) 權限。若因為某種理由，Apps 嘗試將權限變更為隱性權限，就會產生錯誤。為了避免這種錯誤，可透過 `PermissionSettings.isExplicit()` 函式而檢查是否為顯性權限。

```js
// Let's check all installed apps
var apps = navigator.mozApps.mgmt.getAll();

apps.onsuccess = function () {
  var permission = navigator.mozPermissionSettings;

  // Let's grant the permission of each app
  apps.result.forEach(function (app) {
    var request, appName = app.manifest.name;

    for (request in app.manifest.permission) {
      // If the permission is not explicit
      if (!permission.isExplicit(request, app.manifestUrl, app.origine, false) {
        // Let's ask the user for all permissions requested by the application
        permission.set(request, app.manifestUrl, app.origine, false);
      }
    }
  });
}
```

規格
--

不屬於任何規格。

另可參閱
----

* `navigator.mozPermissionSettings`
* `PermissionSettings`


MessageEvent - Web APIs

MessageEvent
============

當伺服器傳來資料時，客戶端會收到一個 `MessageEvent`，由 `WebSocket` 物件 `onmessage` 表示的監聽器接收。

屬性
--

| 屬性 | 形態 | 描述 |
| --- | --- | --- |
| `data` | `DOMString` | `Blob` | `ArrayBuffer` | 伺服器傳來的資料。 |

規範
--

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

瀏覽器兼容
-----

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

參見
--

* `WebSocket`


WebVTT - Web APIs

WebVTT
======

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
WebVTT 是一種 UTF-8 編碼的文字檔案格式，可藉由 `<track>` (en-US) 元素顯示加註時間資訊之文字軌，其主要設計目的是為 `<video>` (en-US) 顯示字幕。

WebVTT 當中可以採用空白或分隔字元（tab）。

WebVTT 的 MIME Type 為 `text/vtt`。

WebVTT 文本
---------

WebVTT 檔的結構中，有兩項必備資訊、四項選用資訊。

* 選用：byte order mark (BOM)
* 字串 `WEBVTT`
* 選用：於 `WEBVTT` 右側可加上文字標題
    + 在 `WEBVTT` 之後至少要有一個空白字元
    + 可以藉此為檔案加上描述
    + 除了換行字元及`「-->`」字串外，可以是任何文字
* 一個空白行，由兩個連續的換行字元構成。
* 選用：一個以上的時間節點（cue）或註解
* 選用：一個以上的空白行

##### 範例 1 - 最簡單的 WEBVTT 檔
```

  WEBVTT
```

##### 範例 2 - 很簡單的 WebVTT 檔
```

  WEBVTT - 這個檔案沒有時間節點
```

##### 範例 3 - 常見的 WebVTT 例子
```

  WEBVTT - 這個檔案有時間節點

  14
  00:01:14.815 --> 00:01:18.114
  - What?
  - Where are we now?

  15
  00:01:18.171 --> 00:01:20.991
  - This is big bat country.

  16
  00:01:21.058 --> 00:01:23.868
  - [ Bats Screeching ]
  - They won't get in your hair. They're after the bugs.
```

WebVTT 註解
---------

Comments are an optional component that can be used to add information to a WebVTT file. Comments are intended for those reading the file and are not seen by users. Comments may contain newlines but it cannot contain a blank line, which is equivalent to two consecutive newlines. A blank line signifies the end of a comment.

註解中不能包含「`-->」字串、「`&」符號或「<」符號。如欲使用後兩者，可採跳脫字串「&」或「<」。此外雖規格上允許使用「>」字元，仍然建議跳脫為「>」以避免混淆。

註解由三個部分組成：

* 字串 `NOTE`
* 一個空白字元或換行字元
* 選用：一個以上的字元，除了前面提到的禁用字元外皆可使用

##### 範例 4 - 常見 WebVTT 範例
```

  NOTE 這行是註解
```

##### 範例 5 - 多行註解
```

  NOTE
  這也是註解，
  只是拆成多行。

  NOTE 當然也可以像這樣
  來分行寫註解。
```

##### 範例 6 - 常見註解使用方式
```

  WEBVTT - 翻譯我喜歡的影片字幕

  NOTE
  本字幕由 Kyle 翻譯，
  希望可以讓我的朋友跟家人一同觀賞。

  1
  00:02:15.000 --> 00:02:20.000
  - Ta en kopp varmt te.
  - Det är inte varmt.

  2
  00:02:20.000 --> 00:02:25.000
  - Har en kopp te.
  - Det smakar som te.

  NOTE This last line may not translate well.

  3
  00:02:25.000 --> 00:02:30.000
  -Ta en kopp.
```

WebVTT 時間節點
-----------

時間節點（cue）是具備單一開始時間、結束時間、文字內容的字幕區段。 Example 6 consists of the header, a blank line, and then five cues separated by blank lines. 時間節點由五個部分組成：

* 選用：時間節點 ID，後接著一個換行字元
* 時間資訊
* 選用：時間節點設定，每個設定值以空白字元分隔，第一個設定值前也要加個空白字元
* 一個以上的換行字元
* 文字內容

##### 範例 7 - Example of a cue
```

1 - Title Crawl
00:00:5.000 --> 00:00:10.000 line:0 position:20% size:60% align:start
Some time ago in a place rather distant....
```

### 節點 ID

此 ID 代表時間節點的名稱，可以用以在腳本語言中參照某段特定時間節點。ID 中禁用換行字元，也不可以包括「`-->」字串。`ID 最後必須以一個換行字元作為結束。

雖然通常都用數字（1, 2, 3...）作為 ID，但規格上並不要求每個 ID 都是為一值。

##### 範例 8 - 範例 7 中的時間節點 ID
```

1 - Title Crawl
```

##### 範例 9 - ID 常見用法
```

WEBVTT

1
00:00:22.230 --> 00:00:24.606
This is the first subtitle.

2
00:00:30.739 --> 00:00:34.074
This is the second.

3
00:00:34.159 --> 00:00:35.743
Third
```

### 時間資訊

時間資訊標注了此段節點的出現時機，其中包括開始時間與結束時間。結束時間必須比開始時間晚，而開始時間必須比先前所有的開始時間晚，或至少是同一時間。

不同時間節點可以設定為同時顯示，但若 WebVTT 檔案是用在 chapters（`<track>` (en-US) 的 `kind` (en-US) 設定為 `chapters`），則不允許兩段節點同時出現。

每項時間資訊都由五個部分組成：

* 開始時間
* 一個以上的空白字元
* 「`-->」字串`
* 一個以上的空白字元
* 結束時間
    + 必須比開始時間晚

時間的表示方式，可以是以下兩種：

* `mm:ss.ttt`
* `hh:mm:ss.ttt`

其中的各元素說明如下：

* `hh` - 小時
    + 至少要有兩個數字，不小於 01
    + 可以超過兩個數字（例如 9999:00:00.000）
* `mm` - 分
    + 從 00 到 59
* `ss` - 秒
    + 從 00 到 59
* `ttt` - 毫秒
    + 從 000 到 999

##### Example 10 - Basic cue timing examples
```

00:22.230 --> 00:24.606
00:30.739 --> 00:00:34.074
00:00:34.159 --> 00:35.743
00:00:35.827 --> 00:00:40.122
```

##### Example 11 - Overlapping cue timing examples
```

00:00:00.000 --> 00:00:10.000
00:00:05.000 --> 00:01:00.000
00:00:30.000 --> 00:00:50.000
```

##### Example 12 - Non-overlapping cue timing examples
```

00:00:00.000 --> 00:00:10.000
00:00:10.000 --> 00:01:00.581
00:01:00.581 --> 00:02:00.100
00:02:01.000 --> 00:02:01.000
```

### Cue Settings

Cue settings are optional components used to position where the cue payload text will be displayed over the video. This includes whether the text is displayed horizontally or vertically. There can be zero or more of them, and they can be used in any order so long as each setting is used no more than once.

The cue settings are added to the right of the cue timings. There must be one or more spaces between the cue timing and the first setting and between each setting. A setting's name and value are separated by a colon. The settings are case sensitive so use lower case as shown. There are five cue settings:

* **vertical**
    + 水平方向

| Table 1 - vertical values |
| --- |
| `vertical:rl` | 文字方向由右至左 |
| `vertical:lr` | 文字方向由左至右 |
* **line**
    + Specifies where text appears vertically. If vertical is set, line specifies where text appears horizontally.
    + Value can be a line number
        - The line height is the height of the first line of the cue as it appears on the video
        - Positive numbers indicate top down
        - Negative numbers indicate bottom up
    + Or value can be a percentage
        - Must be an integer (i.e. no decimals) between 0 and 100 inclusive
        - Must be followed by a percent sign (%)

| Table 2 - line examples |
| --- |
|  | `vertical` 省略時 | `vertical:rl` | `vertical:lr` |
| --- | --- | --- | --- |
| `line:0` | top | right | left |
| `line:-1` | bottom | left | right |
| `line:0%` | top | right | left |
| `line:100%` | bottom | left | right |
* **position**
    + Specifies where the text will appear horizontally. If vertical is set, position specifies where the text will appear vertically.
    + Value is a percentage
    + Must be an integer (no decimals) between 0 and 100 inclusive
    + Must be followed by a percent sign (%)

| Table 3 - position examples |
| --- |
|  | `vertical` 省略時 | `vertical:rl` | `vertical:lr` |
| --- | --- | --- | --- |
| `position:0%` | left | top | top |
| `position:100%` | right | bottom | bottom |
* **size**
    + Specifies the width of the text area. If vertical is set, size specifies the height of the text area.
    + Value is a percentage
    + Must be an integer (i.e. no decimals) between 0 and 100 inclusive
    + Must be followed by a percent sign (%)

| Table 4 - size examples |
| --- |
|  | `vertical` 省略時 | `vertical:rl` | `vertical:lr` |
| --- | --- | --- | --- |
| `size:100%` | full width | full height | full height |
| `size:50%` | half width | half height | half height |
* **align**
    + Specifies the alignment of the text. Text is aligned within the space given by the size cue setting if it is set.

| Table 5 - align values |
| --- |
|  | `vertical` 省略時 | `vertical:rl` | `vertical:lr` |
| --- | --- | --- | --- |
| `align:start` | left | top | top |
| `align:middle` | centred horizontally | centred vertically | centred vertically |
| `align:end` | right | bottom | bottom |

##### Example 13 - Cue setting examples

The first line demonstrates no settings. The second line might be used to overlay text on a sign or label. The third line might be used for a title. The last line might be used for an Asian language.
```

00:00:5.000 --> 00:00:10.000
00:00:5.000 --> 00:00:10.000 line:63% position:72% align:start
00:00:5.000 --> 00:00:10.000 line:0 position:20% size:60% align:start
00:00:5.000 --> 00:00:10.000 vertical:rt line:-1 align:end
```

### 文字內容

The payload is where the main information or content is located. In normal usage the payload contains the subtitles to be displayed. The payload text may contain newlines but it cannot contain a blank line, which is equivalent to two consecutive newlines. A blank line signifies the end of a cue.

文字內容中不能包含「`-->」字串、「`&」符號或「<」符號。如欲使用後兩者，可採跳脫字串「&」或「<」。此外雖規格上允許使用「>」字元，仍然建議跳脫為「>」以避免混淆。若你使用 WebVTT 檔作為後設資料，則可不管這些限制。

除了上述的三個跳脫字串外，還有其他四種跳脫字串，分列如下

| Table 6 - 跳脫字串 |
| --- |
| 名稱 | 字元 | 跳脫字串 |
| --- | --- | --- |
| 「與」 | & | `&` |
| 小於 | < | `<` |
| 大於 | > | `>` |
| 左到右標記 |  | `` |
| 右到左標記 |  | `` |
| 不斷行空白 |  | ` ` |

### 文字內容中的標籤

有很多標籤（例如 `<bold>`）可以用在文字內容中，但若 `<track>` (en-US) 的 `kind` (en-US) 設定為 `chapters` 時，其中所用的 WebVTT 檔案裡就不能使用標籤。

**時間標籤**

時間標籤中的時間，必須比該節點的開始時間晚、比同節點先前之其他時間標籤晚，並且早於該節點的結束時間。*當前文字（active text）* 代表此時間標籤到下個時間標籤（或文字內容的結尾）之間的文字，其他同節點中，比*當前文字* 早的文字都稱為*先前文字（previous text）* ，而晚於*當前文字* 的便稱為*未來文字（future text）* 。如此便可做出卡拉 OK 字幕效果

##### Example 12 - Karaoke style text
```

1
00:16.500 --> 00:18.500
When the moon <00:17.500>hits your eye

1
00:00:18.500 --> 00:00:20.500
Like a <00:19.000>big-a <00:19.500>pizza <00:20.000>pie

1
00:00:20.500 --> 00:00:21.500
That's <00:00:21.000>amore
```

以下則需要開頭標籤與結束標籤（例如 `<b>text</b>`）。

**Class 標籤**（`<c></c>`）

以 CSS 類別為該段文字設定樣式

##### Example 14 - Class tag
```

<c.classname>text</c>
```

**Italics tag** (`<i></i>`)

Italicize the contained text.

##### Example 15 - Italics tag
```

<i>text</i>
```

**Bold tag** (`<b></b>`)

Bold the contained text.

##### Example 16 - Bold tag
```

<b>text</b>
```

**Underline tag** (`<u></u>`)

Underline the contained text.

##### Example 17 - Underline tag
```

<u>text</u>
```

**Ruby tag** (`<ruby></ruby>`)

Used with ruby text tags to display ruby characters (i.e. small annotative characters above other characters).

##### Example 18 - Ruby tag
```

<ruby>WWW<rt>World Wide Web</rt>oui<rt>yes</rt></ruby>
```

**Ruby text tag** (`<rt></rt>`)

Used with ruby tags to display ruby characters (i.e. small annotative characters above other characters).

##### Example 19 - Ruby text tag
```

<ruby>WWW<rt>World Wide Web</rt>oui<rt>yes</rt></ruby>
```

**Voice tag** (`<v></v>`)

Similar to class tag, also used to style the contained text using CSS.

##### Example 20 - Voice tag
```

<v Bob>text</v>
```

瀏覽器支援
-----

### api.VTTCue

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

### api.TextTrack

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

### api.VTTRegion

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

規格
--

* http://dev.w3.org/html5/webvtt/


AnimationEvent - Web APIs

AnimationEvent
==============

**實驗性質:** **這是一個實驗中的功能 (en-US)**
此功能在某些瀏覽器尚在開發中，請參考兼容表格以得到不同瀏覽器用的前輟。

摘要
--

**`AnimationEvent`** 介面表現提供動畫 (en-US)相關資訊的事件。

Event

AnimationEvent性能
--

*另外從其父 `Event` 繼承屬性*。

`AnimationEvent.animationName` (en-US) Read only

是一個`DOMString`包含的值 `animation-name` (en-US) CSS 屬性與過渡有關。

`AnimationEvent.elapsedTime` (en-US) Read only

是一個`float`給予時間的動畫已經運行，以秒為單位，當該事件燒製，不含動畫被暫停的任何時間量。為一個`"animationstart"`事件，`elapsedTime`是`0.0`，除非有一個負值`animation-delay` (en-US)，在這種情況下，該事件將與燒製`elapsedTime`含有 `(-1 * delay)`。

`AnimationEvent.pseudoElement` (en-US) Read only

是一個`DOMString`，從`"::"`，包含的名字虛擬元素 (en-US)的動畫運行。如果動畫上不偽元素，但該元素，一個空字符串上運行`：''。`

構造函數
----

`AnimationEvent()` (en-US)

創建一個`AnimationEvent`事件具有給定參數。

方法
--

*同時繼承其父`事件`方法*。

`AnimationEvent.initAnimationEvent()` (en-US)
非標準

已棄用

初始化`AnimationEvent` 使用過時的創建 `Document.createEvent("AnimationEvent")` 方法。

規範
--

| Specification |
| --- |
| CSS Animations Level 1 # interface-animationevent |

瀏覽器兼容性
------

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

另請參見
----

* 使用 CSS 動畫 (en-US)
* Animation-related CSS properties and at-rules: `animation` (en-US), `animation-delay` (en-US), `animation-direction` (en-US), `animation-duration` (en-US), `animation-fill-mode`, `animation-iteration-count` (en-US), `animation-name` (en-US), `animation-play-state` (en-US), `animation-timing-function` (en-US), `@keyframes` (en-US).


MediaDevices - Web APIs

MediaDevices
============

`MediaDevices`介面可以存取連接的媒體輸入設備，像是相機、麥克風，以及螢幕分享。它可以存取任何硬體資源的媒體數據。

EventTarget

MediaDevices屬性
--

*繼承父類`EventTarget`的屬性。*

方法
--

*繼承父類`EventTarget`的方法。*

`enumerateDevices()`

取得一系列關於系統中可用的媒體輸入和媒體輸出設備的資訊。

`getSupportedConstraints()` (en-US)

返回一個符合 `MediaTrackSupportedConstraints` (en-US) 的物件，該物件標示出 `MediaStreamTrack` (en-US) 介面支援哪些可約束的屬性。請參考 Media Streams API (en-US) 瞭解更多關於 `constraints` 的資訊。

`getDisplayMedia()` (en-US)

出現提示視窗讓使用者選擇要捕捉整個螢幕或是部分(例如一個視窗)的畫面做為`MediaStream` (en-US)，用於分享或錄製。返回值為一個解析為`MediaStream` 的 promise。

`getUserMedia()` (en-US)

透過提示視窗獲得使用者的許可後，打開系統上的相機和/或麥克風麥克風，並返回一包含視訊輸入軌道和/或音訊輸入軌道的`MediaStream` (en-US)。

`selectAudioOutput()` (en-US)

出現提示視窗讓使用者選擇特定的音訊輸出設備。

事件
--

`devicechange` (en-US)

在媒體輸入或媒體輸出設備連接上使用者的系統裝置，或是從使用者的系統裝置移除時觸發。

範例
--

```js
"use strict";

// Put variables in global scope to make them available to the browser console.
var video = document.querySelector("video");
var constraints = (window.constraints = {
  audio: false,
  video: true,
});
var errorElement = document.querySelector("#errorMsg");

navigator.mediaDevices
  .getUserMedia(constraints)
  .then(function (stream) {
    var videoTracks = stream.getVideoTracks();
    console.log("Got stream with constraints:", constraints);
    console.log("Using video device: " + videoTracks[0].label);
    stream.onremovetrack = function () {
      console.log("Stream ended");
    };
    window.stream = stream; // make variable available to browser console
    video.srcObject = stream;
  })
  .catch(function (error) {
    if (error.name === "ConstraintNotSatisfiedError") {
      errorMsg(
        "The resolution " +
          constraints.video.width.exact +
          "x" +
          constraints.video.height.exact +
          " px is not supported by your device.",
      );
    } else if (error.name === "PermissionDeniedError") {
      errorMsg(
        "Permissions have not been granted to use your camera and " +
          "microphone, you need to allow the page access to your devices in " +
          "order for the demo to work.",
      );
    }
    errorMsg("getUserMedia error: " + error.name, error);
  });

function errorMsg(msg, error) {
  errorElement.innerHTML += "<p>" + msg + "</p>";
  if (typeof error !== "undefined") {
    console.error(error);
  }
}
```

規範
--

| Specification |
| --- |
| Media Capture and Streams # mediadevices |

瀏覽器兼容性
------

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

參見
--

* Media Capture and Streams API: The API this interface is part of.
* Screen Capture API (en-US): The API defining the `getDisplayMedia()` (en-US) method.
* WebRTC API (en-US)
* `Navigator.mediaDevices` (en-US): Returns a reference to a `MediaDevices` object that can be used to access devices.
* CameraCaptureJS: HTML5 video capture and playback using `MediaDevices` and the MediaStream Recording API (source on GitHub)
* OpenLang: HTML5 video language lab web application using `MediaDevices` and the MediaStream Recording API for video recording (source on GitHub)


IndexedDB - Web APIs

IndexedDB
=========

**實驗性質:** **這是一個實驗中的功能 (en-US)**
此功能在某些瀏覽器尚在開發中，請參考兼容表格以得到不同瀏覽器用的前輟。

IndexedDB 為用戶端的儲存用 API，可用於大量的結構化資料，並透過索引功能而高效率搜尋資料。DOM Storage (en-US) 適合儲存較少量的資料；IndexedDB 則適合大量結構化資料的儲存方案。

本篇文章僅為 API 物件的入門技術說明。若需進一步了解，則請參閱 IndexedDB 基本概念。更多細節則可參閱使用 IndexedDB。

IndexedDB 提供不同 APIs 用於同步與非同步的存取作業。同步 API 僅能用於Web Workers (en-US) 之中，但尚未有瀏覽器支援同步 API。非同步 API 則用於 Web Workers 內外均可，但 Firefox 目前尚未建構。

非同步 API
-------

非同步 API 不會阻塞呼叫它的執行緒。若要非同步存取資料庫，可於 window (en-US) 物件的 indexedDB 屬性上呼叫 open (en-US)()。此函式將回傳 IDBRequest 物件 (IDBOpenDBRequest)，開始非同步存取資料庫；呼叫端程式利用 IDBRequest 物件上的事件來進行非同步溝通。

**備註：** 在舊版瀏覽器 (Gecko 16 版之前的 indexedDB 屬性；Chrome 中的 webkitIndexedDB；IE 10 中的 msIndexedDB) 中的 indexedDB 物件，均具備前綴屬性。

* `IDBFactory` (en-US) 可存取資料庫。此介面是透過全域物件 `indexedDB` 所建構，因此成為 API 的切入點。
* `IDBCursor` (en-US) 將依序存取物件與索引。
* `IDBCursorWithValue` (en-US) 將依序存取物件與索引，並回傳指標 (Cursor) 的目前數值。
* `IDBDatabase` (en-US) 代表到資料庫的連線。這也是能與資料庫互動的唯一方式。
* `IDBEnvironment` 可存取用戶端的資料庫。此介面是透過 window (en-US) 物件所建構。
* `IDBIndex` (en-US) 可存取索引的 Metadata。
* `IDBKeyRange` (en-US) 定義資料鍵範疇。
* `IDBObjectStore` (en-US) 代表物件存檔。
* `IDBOpenDBRequest` (en-US) 代表「開啟資料庫」的請求。
* `IDBRequest` (en-US) 代表向非同步資料庫和資料庫物件發出之請求，也就是呼叫非同步方法後回傳值。
* `IDBTransaction` (en-US) 代表一個交易。我們可以和資料庫進行交易，例如要求存取某一個物件存檔，以及決定要執行讀或寫的存取作業。
* `IDBVersionChangeEvent` (en-US) `則代表資料庫所變更的版本。`

以下 API 在早期規範中有定義，但現已移除。這邊列出僅供參考:

* IDBVersionChangeRequest 代表「更改資料庫版本」的請求。更改資料庫版本的方法已有不同 (呼叫 IDBFactory.open() (en-US) 而不需同時呼叫 IDBDatabase.setVersion() (en-US))；而且IDBOpenDBRequest (en-US)已經整合了從 IDBVersionChangeRequest 中所移除之功能。
* IDBDatabaseException
已棄用
 在執行資料庫作業時，代表可能遭遇的例外狀況。

除了非同步 API，也有應用在WebWorkers (en-US)內的同步 API，但請注意目前還沒有瀏覽器支援同步 API。這裡也提供 API 的同步版本 (en-US)。

儲存限制
----

單一資料庫項目的容量/大小並沒有任何限制，但是各個 IndexedDB 資料庫的容量就有限制。此限制，還有使用者介面的斷言 (Assert) 方式，又將因瀏覽器而有所不同：

* Firefox：對 IndexedDB 資料庫的容量並無限制。但若要儲存的 Blobs 超過 50 MB，使用者介面將會要求權限。若要修改此容量，則可透過 dom.indexedDB.warningQuota (可至 http://mxr.mozilla.org/mozilla-central/source/modules/libpref/src/init/all.js 中設定) 設定自己所需的限制。
* Google Chrome：請參閱 https://developers.google.com/chrome...rage#temporary
範例
--

Web 上的 IndexedDB 使用範例，是由 Marco Castelluccio 所提供。Marco 是 IndexedDB Mozilla DevDerby 的優勝者，而該得獎 Demo 為 eLibri，屬於函式庫與 eBook 閱讀器的 App。

另可參閱
----

* IndexedDB 基本概念
* 使用 IndexedDB
* 在 IndexedDB 中儲存影像與檔案
* 使用 HTML5 IndexedDB 的簡易 TODO 清單

**備註：** 此線上教學是根據較舊版本的規格所列，因此無法搭配最新版的瀏覽器。新版本已移除其中的 `setVersion()` 函式。
* Indexed Database API 規格
* IndexedDB — 儲存於自己的瀏覽器中
* IndexedDB 範例
* 僅支援 WebSQL 的瀏覽器 (例如行動 WebKit)，可適用 IndexedDB Polyfill
* JQuery IndexedDB 外掛程式


DocumentFragment - Web APIs

DocumentFragment
================

**`DocumentFragment`** 介面表示了一個沒有父節點的最小化文件物件。`DocumentFragment` 被當作一種輕量化的 `Document` (en-US)，用如同標準文件一般的方式保存片段的文件結構（由節點組成）。關鍵的區別在於文件片段不是真實的 DOM 結構，文件片段的變動並不會影響目前的網頁文件，也不會導致回流（reflow）或引起任何影響效能的情況發生。

一般的用法是建立一個 `DocumentFragment` 物件，在此物件中組織一個 DOM 的子樹。再使用 `Node` (en-US) 介面定義的方法，如 `appendChild()` (en-US) 或 `insertBefore()` (en-US) 將這個文件片段加入或插入目前頁面的 DOM 當中。執行這個將文件片段中的節點置入 DOM 的動作之後，會留下一個空的 `DocumentFragment` 物件（只會插入物件中的節點，`DocumentFragment` 物件本身不會被插入）。由於文件片段中的所有節點是一次性的被插入目前頁面文件當中，故回流及頁面渲染只會被觸發一次，所以可用插入 `DocumentFragment` 物件的方式取代傳統分別插入多個節點至 DOM（將節點一個一個分次進行插入）的操作方式。

此介面也適合與 Web components 搭配使用：`<template>` 元素在其 `HTMLTemplateElement.content` (en-US) 屬性中便包含了一個 `DocumentFragment` 物件。

可使用 `document.createDocumentFragment()` 方法或 `DocumentFragment` 的建構式來建立一個空的 `DocumentFragment` 物件。

屬性
--

*This interface has no specific properties, but inherits those of its parent,* *`Node` (en-US), and implements those of the `ParentNode` interface.*

`ParentNode.children` Read only
實驗性質

Returns a live `HTMLCollection` (en-US) containing all objects of type `Element` (en-US) that are children of the `DocumentFragment` object.

`ParentNode.firstElementChild` Read only
實驗性質

Returns the `Element` (en-US) that is the first child of the `DocumentFragment` object, or `null` if there is none.

`ParentNode.lastElementChild` (en-US) Read only
實驗性質

Returns the `Element` (en-US) that is the last child of the `DocumentFragment` object, or `null` if there is none.

`ParentNode.childElementCount` (en-US) Read only
實驗性質

Returns an `unsigned long` giving the amount of children that the `DocumentFragment` has.

建構式
---

`DocumentFragment()` (en-US)
實驗性質

Returns an empty `DocumentFragment` object.

方法
--

*This interface inherits the methods of its parent, `Node` (en-US), and implements those of the `ParentNode` interface.*

`DocumentFragment.find()`
實驗性質

Returns the first matching `Element` (en-US) in the tree of the `DocumentFragment`.

`DocumentFragment.findAll()`
實驗性質

Returns a `NodeList` of matching `Element` (en-US) in the tree of the `DocumentFragment`.

`DocumentFragment.querySelector()` (en-US)

Returns the first `Element` (en-US) node within the `DocumentFragment`, in document order, that matches the specified selectors.

`DocumentFragment.querySelectorAll()` (en-US)

Returns a `NodeList` of all the `Element` (en-US) nodes within the `DocumentFragment` that match the specified selectors.

`DocumentFragment.getElementById()` (en-US)

Returns the first `Element` (en-US) node within the `DocumentFragment`, in document order, that matches the specified ID.

規範
--

| Specification |
| --- |
| DOM Standard # interface-documentfragment |

瀏覽器相容性
------

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

參見
--

* The DOM interfaces index.


使用全螢幕模式 - Web APIs

使用全螢幕模式
=======

全螢幕 API 提供一個簡便的方式使網頁可以使用佔用使用者的整個螢幕的方式來顯示內容。該 API 讓你能夠容易地指示瀏覽器使某個元素及其子系（如有）佔用整個螢幕，並隱藏螢幕上所有瀏覽器使用者介面及其他應用程式。

**備註：** 目前並非所有瀏覽器均使用 API 的沒有前綴的版本。請查閱有關前綴以及名稱差異的表格（你也可以使用 Fscreen 來提供跨瀏覽器 API 存取）。

啟動全螢幕模式
-------

如果你有一個元素打算以全螢幕模式展示（例如 `<video>` (en-US)），你可以呼叫該元素之 `Element.requestFullscreen()` (en-US) 方法使之以全螢幕模式顯示。

考慮此 `<video>` (en-US) 元素：

```html
<video controls id="myvideo">
  <source src="somevideo.webm"></source>
  <source src="somevideo.mp4"></source>
</video>
```

我們可以使用指令碼將此影片全螢幕顯示：

```js
var elem = document.getElementById("myvideo");
if (elem.requestFullscreen) {
  elem.requestFullscreen();
} else if (elem.msRequestFullscreen) {
  elem.msRequestFullscreen();
} else if (elem.mozRequestFullScreen) {
  elem.mozRequestFullScreen();
} else if (elem.webkitRequestFullscreen) {
  elem.webkitRequestFullscreen();
}
```

### 呈現差異

值得留意的是，Gecko 及 WebKit 的實作有關鍵分別：Gecko 會增加 CSS 規則讓全螢幕的元素展延至填滿整個螢幕："`width: 100%; height: 100%`"。WebKit 則不會執行此動作，取而代之的是把該元素置中，並以原先的大小顯示。要取得同樣的全螢幕行為，你需要為該元素自行添加 "`width: 100%; height: 100%;`" 的 CSS 規則：

```css
#myvideo:-webkit-full-screen {
  width: 100%;
  height: 100%;
}
```

另一方面，如果你嘗試在 Gecko 上模擬 WebKit 的行為，你需要把呈現的元素放置在另一個實際調整為全螢幕的元素裡面，再使用 CSS 規則來調整內部元素至你想要的外觀。

### 通知

如果成功進入全螢幕模式，包含該元素的文件將會接收到 `fullscreenchange` (en-US) 事件。當離開全螢幕模式時，則會收到 `fullscreenchange` (en-US) 事件。注意 `fullscreenchange` (en-US) 事件並不提供任何資訊指示進入或離開全螢幕模式，但如果文件的 `fullscreenElement` (en-US) 屬性的值不為 null，則表示你正在處於全螢幕模式。

### 全螢幕要求失敗

並不是所有情況下都保證可以進入全螢幕模式。例如，`<iframe>` (en-US) 元素含有 `allowfullscreen` (en-US) 屬性來選擇是否容許其內容能以全螢幕方式呈現。而且，例如視窗式外掛程式等的某些內容並不可以在全螢幕模式中顯示。把無法呈現為全螢幕的元素設定為全螢幕模式的嘗試都沒有作用，而要求顯示為全螢幕的元素會接收到 `mozfullscreenerror` 事件。當全螢幕要求失敗時，Firefox 會在網頁主控台上紀錄一則錯誤訊息，解釋要求失敗的原因。但在 Chrome 以及新版的 Opera 上，則不會產生這些錯誤訊息。

**備註：** 全螢幕要求必須在事件處理常式中呼叫，否則將會被拒絕。

離開全螢幕模式
-------

使用者永遠可以自行離開全螢幕模式，詳見 Things your users want to know。你也可以呼叫 `Document.exitFullscreen()` (en-US) 方法來達到相同效果。

其他資訊
----

`document` (en-US) 提供一些附加資訊，對於開發全螢幕網頁應用程式的時候非常有用：

`fullscreenElement` (en-US)

`fullscreenElement` 屬性傳回正在顯示為全螢幕模式的 `element` (en-US)。如其為非 null 值，表示文件目前在全螢幕模式。如其為 null，表示文件目前不在全螢幕模式。

`fullscreenEnabled` (en-US)

`fullscreenEnabled` 屬性傳回文件是否容許你要求進入全螢幕訊息。

使用者可能想了解的訊息
-----------

你可能會讓使用者知道他們可以按 `ESC` 或 `F11` 鍵來離開全螢幕模式。

此外，瀏覽其他頁面、切換分頁、或切換到其他應用程式（例如按 鍵）亦會離開全螢幕模式。

範例
--

In this example, a video is presented in a web page. Pressing the Return or Enter key lets the user toggle between windowed and fullscreen presentation of the video.

查看示例

### 監視 Enter 鍵

When the page is loaded, this code is run to set up an event listener to watch for the 'enter' key.

```js
document.addEventListener(
  "keydown",
  function (e) {
    if (e.keyCode == 13) {
      toggleFullScreen();
    }
  },
  false,
);
```

### Toggling fullscreen mode

This code is called when the user hits the Enter key, as seen above.

```js
function toggleFullScreen() {
  if (
    !document.fullscreenElement && // alternative standard method
    !document.mozFullScreenElement &&
    !document.webkitFullscreenElement &&
    !document.msFullscreenElement
  ) {
    // current working methods
    if (document.documentElement.requestFullscreen) {
      document.documentElement.requestFullscreen();
    } else if (document.documentElement.msRequestFullscreen) {
      document.documentElement.msRequestFullscreen();
    } else if (document.documentElement.mozRequestFullScreen) {
      document.documentElement.mozRequestFullScreen();
    } else if (document.documentElement.webkitRequestFullscreen) {
      document.documentElement.webkitRequestFullscreen(
        Element.ALLOW\_KEYBOARD\_INPUT,
      );
    }
  } else {
    if (document.exitFullscreen) {
      document.exitFullscreen();
    } else if (document.msExitFullscreen) {
      document.msExitFullscreen();
    } else if (document.mozCancelFullScreen) {
      document.mozCancelFullScreen();
    } else if (document.webkitExitFullscreen) {
      document.webkitExitFullscreen();
    }
  }
}
```

This starts by looking at the value of the `fullscreenElement` attribute on the `document` (en-US) (checking it prefixed with both `moz`, `ms`, and `webkit`). If it's `null`, the document is currently in windowed mode, so we need to switch to fullscreen mode. Switching to fullscreen mode is done by calling either `element.mozRequestFullScreen()` (en-US) `msRequestFullscreen()`or `webkitRequestFullscreen()`, depending on which is available.

If fullscreen mode is already active (`fullscreenElement` is non-`null`), we call `document.mozCancelFullScreen()` (en-US), `msExitFullscreen` or `webkitExitFullscreen()`, again depending on which browser is in use.

規範
--

| Specification |
| --- |
| Fullscreen API Standard # ref-for-dom-document-fullscreenelement① |
| Fullscreen API Standard # ref-for-dom-document-fullscreenenabled① |
| Fullscreen API Standard # ref-for-dom-document-exitfullscreen① |
| Fullscreen API Standard # ref-for-dom-element-requestfullscreen① |
| Fullscreen API Standard # dom-document-fullscreen |

瀏覽器兼容性
------

### api.Document.fullscreenElement

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

### api.Document.fullscreenEnabled

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

### api.Document.exitFullscreen

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

### api.Element.requestFullscreen

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

### api.Document.fullscreen

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

非標準方法
-----

These are some of the methods that browsers implemented before the standard was drafted. Having the standard methods described above it's better to avoid using the following ones:

* `window.fullScreen` (en-US) (Firefox)
* `HTMLMediaElement.webkitDisplayingFullscreen`
* `HTMLMediaElement.webkitEnterFullscreen`
* `HTMLMediaElement.webkitExitFullscreen`
* `HTMLMediaElement.webkitSupportsFullscreen`
參見
--

* `element.mozRequestFullScreen()` (en-US)
* `element.mozCancelFullScreen()`
* `document.mozFullScreen` (en-US)
* `document.mozFullScreenElement` (en-US)
* `document.mozFullScreenEnabled` (en-US)
* `:-moz-full-screen` (en-US)
* `:-moz-full-screen-ancestor`
* `allowfullscreen` (en-US)
* Blog post: Firefox's HTML full-screen API enabled in Nightly builds


Geolocation.getCurrentPosition() - Web APIs

Geolocation.getCurrentPosition()
================================

**`Geolocation.getCurrentPosition()`** 方法用來獲取設備當前的位置。

語法
--
```

navigator.geolocation.getCurrentPosition(success[, error[, options]])
```

### 參數

*success*

一個回呼函式(callback function) 會被傳入一個`Position` 的物件。

*error* 選擇性

一個選擇性的錯誤回呼函式(callback function)，會被傳入一個 `PositionError` 的物件。

*options* 選擇性

一個選擇性的 `PositionOptions` 的物件。

範例
--

```js
var options = {
  enableHighAccuracy: true,
  timeout: 5000,
  maximumAge: 0,
};

function success(pos) {
  var crd = pos.coords;

  console.log("Your current position is:");
  console.log("Latitude : " + crd.latitude);
  console.log("Longitude: " + crd.longitude);
  console.log("More or less " + crd.accuracy + " meters.");
}

function error(err) {
  console.warn("ERROR(" + err.code + "): " + err.message);
}

navigator.geolocation.getCurrentPosition(success, error, options);
```

規格
--

| Specification |
| --- |
| Geolocation API # getcurrentposition-method |

瀏覽器的相容性
-------

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

請參考
---

* Using geolocation (en-US)
* `Navigator.geolocation`


Geolocation.clearWatch() - Web APIs

Geolocation.clearWatch()
========================

**`Geolocation.clearWatch()`** 這個函式是用來取消 `Geolocation.watchPosition()` 註冊的函式。

語法
--
```

navigator.geolocation.clearWatch(id);
```

### 參數

*編號(id)*

這個編號(ID) 是由 `Geolocation.watchPosition()` 這個函式所回傳，當你不再需要收到位置更新時，你可以用此編號，取消 `Geolocation.watchPosition()` 的註冊。

範例
--

```js
var id, target, option;

function success(pos) {
  var crd = pos.coords;

  if (target.latitude === crd.latitude && target.longitude === crd.longitude) {
    console.log("Congratulation, you reach the target");
    navigator.geolocation.clearWatch(id);
  }
}

function error(err) {
  console.warn("ERROR(" + err.code + "): " + err.message);
}

target = {
  latitude: 0,
  longitude: 0,
};

options = {
  enableHighAccuracy: false,
  timeout: 5000,
  maximumAge: 0,
};

id = navigator.geolocation.watchPosition(success, error, options);
```

規格
--

| Specification |
| --- |
| Geolocation API # clearwatch-method |

瀏覽器的相容性
-------

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

請參考
---

* Using geolocation (en-US)
* `Geolocation`
* `Geolocation.watchPosition()`
* `Geolocation.getCurrentPosition()`


Geolocation.watchPosition() - Web APIs

Geolocation.watchPosition()
===========================

**`Geolocation.watchPosition()`** 這個方法是用來註冊一個處理的函式，當使用者的裝置位置更新時，這個函式所傳入的回呼函式(callback function) 就會自動被呼叫。你也可以選擇性的定義錯誤時哪些錯誤回呼函式(error callback function) 需要被呼叫。

這個函式將回傳一組 ID 編號，此編號搭配 `Geolocation.clearWatch()` 函式，即可停止更新使用者的位置。

語法
--

```js
watchPosition(success)
watchPosition(success, error)
watchPosition(success, error, options)
```

### 參數

*success*

一個回呼函式(callback function) 會被傳入一個 `Position` 的物件。

*error* 選擇性

一個選擇性的錯誤回呼函式(callback function)，會被傳入一個`PositionError` 的物件。

*options* 選擇性

一個選擇性 `PositionOptions` 的物件。

範例
--

```js
var id, target, options;

function success(pos) {
  var crd = pos.coords;

  if (target.latitude === crd.latitude && target.longitude === crd.longitude) {
    console.log("Congratulations, you reached the target");
    navigator.geolocation.clearWatch(id);
  }
}

function error(err) {
  console.warn("ERROR(" + err.code + "): " + err.message);
}

target = {
  latitude: 0,
  longitude: 0,
};

options = {
  enableHighAccuracy: false,
  timeout: 5000,
  maximumAge: 0,
};

id = navigator.geolocation.watchPosition(success, error, options);
```

備註
--

如果你的應用程式是跑在 firefox OS 上，請參考 geolocation wake lock，此方法可以讓你的程式在背景或螢幕關上時也能持續收到位置更新。

規格
--

| Specification |
| --- |
| Geolocation API # watchposition-method |

瀏覽器的相容性
-------

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

請參考
---

* Using geolocation (en-US)
* 這個介面屬於`Geolocation`. 並且存取他的方式為`NavigatorGeolocation.geolocation` (en-US).
* 相反的操作: `Geolocation.clearWatch()`
* 類似的方法: `Geolocation.getCurrentPosition()`


EventListener - Web APIs

EventListener
=============

**`EventListener`** 介面表示一個可以處理由 `EventTarget` 物件分派事件的物件。

**備註：** 基於相容舊版內容的需要， `EventListener` 可以接受一個函式及一個帶有 `handleEvent()` 屬性函式的物件。相關的範例顯示在下方。

屬性
--

*這個介面並不實作且不繼承任何屬性。*

方法
--

*這個介面不繼承任何方法。*

`EventListener.handleEvent()` (en-US)

一個可以在指定類型事件發生時被呼叫的函數。

範例
--

### HTML

```html
<button id="btn">Click here!</button>
```

### JavaScript

```js
const buttonElement = document.getElementById("btn");

// 透過提供回呼函數的方式對「click」事件新增處理器。
// 當元素被點選後會出現「Element clicked!」的彈出訊息。
buttonElement.addEventListener("click", function (event) {
  alert("Element clicked through function!");
});

// 基於相容性，一個帶有 `handleEvent` 的非函式物件可被視為處理函式。
buttonElement.addEventListener("click", {
  handleEvent: function (event) {
    alert("Element clicked through handleEvent property!");
  },
});
```

### 結果

### 檢閱相關

* addEventListener
規格
--

| Specification |
| --- |
| DOM Standard # ref-for-dom-eventtarget-addeventlistener③ |

瀏覽器相容性
------

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


EventTarget.dispatchEvent() - Web APIs

EventTarget.dispatchEvent()
===========================

於此 `EventTarget` 物件上觸發特定的 `Event` 物件實體，相當於依照註冊的順序呼叫它的 `EventListener`。一般事件處理規則（包含捕捉（capturing）和可選的冒泡（bubbling）階段）也適用於用 `dispatchEvent()` 手動觸發事件。

語法
--
```

cancelled = !target.dispatchEvent(event)
```

### 參數

* `event` 是要被觸發的事件（`Event` 物件）。
* `target` 會被初始化為事件的 `Event.target` 屬性，其也影響了要呼叫哪一個事件監聽器。
### 回傳值

* 會在事件完成傳遞（捕捉、命中、冒泡三階段）之後才回傳其值。
* 若事件在傳遞過程當中，事件是可被取消的（`Event.cancelable` (en-US) 屬性為 `true`）且曾於一個或一個以上的事件處理器中被執行了該事件的 `Event.preventDefault()` 方法（且事件須確實已被取消了預設行為），即回傳 `false`。否則回傳 `true` 值。

若遇到以下 3 種情況，`dispatchEvent` 會拋出錯誤資訊－－ `UNSPECIFIED_EVENT_TYPE_ERR` ：

1. 執行 `dispatchEvent` 前並未藉由初始化事件指定事件類型
2. 事件類型為 `null` 。
3. 事件類型是個空白字串。

這些異常，處理器會報告「異常未捕獲（uncaught exceptions）」；

事件處理器（event handlers）會在一群呼叫堆（nested callstack）上執行：事件的呼叫方（caller）會先由處理器會阻擋暫停執行，直到事件完成才繼續執行，但是要注意的是，事件若發生異常並不會傳回給呼叫方。

注意
--

`dispatchEvent` 是「建立 → 初始化 → 觸發」的最後一步驟。這些步驟是用來觸發事件，讓事件完成。事件有多種建立方式，例如用 `document.createEvent` 並用 initEvent (en-US) 或其他特殊 methods ，像是 initMouseEvent (en-US) 或 initUIEvent (en-US) 來初始化。

詳請可參考《`Event`》。

範例
--

請參閱《建立或觸發事件》。

規格
--

| Specification |
| --- |
| DOM Standard # ref-for-dom-eventtarget-dispatchevent③ |

瀏覽器支援度
------

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


MediaDevices.enumerateDevices() - Web APIs

MediaDevices.enumerateDevices()
===============================

`MediaDevices`方法請求一個可用的媒體輸入與媒體輸出裝置列表，像是麥克風、相機、耳機等等。返回值`Promise`可被解析為一個描述裝置的`MediaDeviceInfo` (en-US)陣列。

對特定設備的存取由Permissions API控制。返回的裝置列表會省略任何未授予相應權限的設備，包括麥克風、相機、揚聲器選擇（對於輸出裝置）等等。

語法
--

```js
enumerateDevices()
```

### 參數

無。

### 返回值

當返回值`Promise`完成時，會得到一個`MediaDeviceInfo` (en-US)物件的陣列。陣列裡的每個物件描述一個可用的媒體輸入與輸出設備（只有被授予權限的裝置），物件的順序是有意義的，預設捕獲的裝置會被列在第一個。

如果枚舉失敗，promise 會被拒絕。

範例
--

以下是一個使用`enumerateDevices()`的範例，它會產生一個帶有標籤的（如果有標籤的話）device ID (en-US)列表。

```js
if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {
  console.log("enumerateDevices() not supported.");
  return;
}

// List cameras and microphones.

navigator.mediaDevices
  .enumerateDevices()
  .then(function (devices) {
    devices.forEach(function (device) {
      console.log(
        device.kind + ": " + device.label + " id = " + device.deviceId,
      );
    });
  })
  .catch(function (err) {
    console.log(err.name + ": " + err.message);
  });
```

這可能會產生：

```bash
videoinput: id = csO9c0YpAf274OuCPUA53CNE0YHlIr2yXCi+SqfBZZ8=
audioinput: id = RKxXByjnabbADGQNNZqLVLdmXlS0YkETYCIbg+XxnvM=
audioinput: id = r2/xw1xUPIyZunfV1lGrKOma5wTOvCkWfZ368XCndm0=
```

或者如果有一個或多個`MediaStream` (en-US)處於活動狀態或是被授予持久性的權限，則將產生：

```bash
videoinput: FaceTime HD Camera (Built-in) id=csO9c0YpAf274OuCPUA53CNE0YHlIr2yXCi+SqfBZZ8=
audioinput: default (Built-in Microphone) id=RKxXByjnabbADGQNNZqLVLdmXlS0YkETYCIbg+XxnvM=
audioinput: Built-in Microphone id=r2/xw1xUPIyZunfV1lGrKOma5wTOvCkWfZ368XCndm0=
```

規範
--

| Specification |
| --- |
| Media Capture and Streams # dom-mediadevices-enumeratedevices |

瀏覽器兼容性
------

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

參見
--

* `MediaDevices.getUserMedia` (en-US)
* WebRTC (en-US) - the introductory page to the API
* MediaStream API - the API for the media stream objects
* Taking webcam photos (en-US) - a
 tutorial on using `getUserMedia()` for taking photos rather than video.


CSSStyleSheet.insertRule() - Web APIs

CSSStyleSheet.insertRule()
==========================

**CSSStyleSheet.insertRule()** 方法新增一個新的 CSS 規則，到當前的樣式表，他伴隨著一些限制.

更明確的說，雖然 **insertRule()** 只是一個 `CSSStyleSheet` (en-US) 的方法， 他實際上插入這份規則到 `CSSStyleSheet` (en-US).*cssRules*, 在 `CSSRuleList` (en-US) 之中。

這份規則，必須包含的內容，取決於它的類型： 對於規則集 (rule-sets)，規則同時指定了選擇器和样式聲明。 對於規則 (at-rules)，規則同時指定 at 標識符（ at-identifier ）和規則內容。

Syntax
------

```js
insertRule(rule)
insertRule(rule, index)
```

### Parameters

`rule`

一個 `DOMString` 包含要被插入的規則，這份規則同時指定了選擇器（selector (en-US)）和样式聲明，或 at 標識符和規則內容。

`index` 選擇性

無符號整數，代表在 `stylesheet.cssRules.length` 中插入的位置，其中 index-0 是第一個規則，而 index-max 就是最後一個規則，並且與 CSSStyleSheet 的長度相同。cssRules 在舊的實現中是必需的。查詢「瀏覽器兼容」取得詳細信息。 默認值為 0。

### Return value

The index within the style sheet's rule-list of the newly inserted rule.

### 限制

 CSS 樣式表規則列表，有一些直覺的、和不是那麼直覺的限制 ，影響著規則的插入方式和位置。
 違反這些可能會導致 DOM 異常 (`DOMException` (en-US)) 引發錯誤。

* 如果 index > 樣式表中規則數量 (`CSSRuleList.length`)，他會中止，顯示 IndexSizeError (索引大小錯誤)。
* 如果 rule 無法在索引 0 插入，因為一些 CSS 因素的限制，他會中止，顯示 HierarchyRequestError (層次結構請求錯誤)。
* 如果規則參數中給出多個規則，他會中止，顯示 SyntaxError (語法錯誤)。
* 如果嘗試在樣式規則之後插入 `@import at-rule`，他會中止，顯示 HierarchyRequestError (層次結構請求錯誤)。
* 如果規則是 `@namespace at-rule`，且列表不只有 `@import at-rules` 和 / 或 `@namespace at-rules`他會中止，顯示 InvalidStateError (狀態錯誤無效)。
Examples
--------

### Example 1

```js
// push a new rule onto the top of my stylesheet
myStyle.insertRule("#blanc { color: white }", 0);
```

### Example 2

```js
/\*\*
 \* Add a stylesheet rule to the document (may be better practice, however,
 \* to dynamically change classes, so style information can be kept in
 \* genuine stylesheets (and avoid adding extra elements to the DOM))
 \* Note that an array is needed for declarations and rules since ECMAScript does
 \* not afford a predictable object iteration order and since CSS is
 \* order-dependent (i.e., it is cascading); those without need of
 \* cascading rules could build a more accessor-friendly object-based API.
 \* @param {Array} rules Accepts an array of JSON-encoded declarations
 \* @example
addStylesheetRules([
 ['h2', // Also accepts a second argument as an array of arrays instead
 ['color', 'red'],
 ['background-color', 'green', true] // 'true' for !important rules
 ],
 ['.myClass',
 ['background-color', 'yellow']
 ]
]);
 \*/
function addStylesheetRules(rules) {
  var styleEl = document.createElement("style"),
    styleSheet;

  // Append style element to head
  document.head.appendChild(styleEl);

  // Grab style sheet
  styleSheet = styleEl.sheet;

  for (var i = 0, rl = rules.length; i < rl; i++) {
    var j = 1,
      rule = rules[i],
      selector = rules[i][0],
      propStr = "";
    // If the second argument of a rule is an array of arrays, correct our variables.
    if (Object.prototype.toString.call(rule[1][0]) === "[object Array]") {
      rule = rule[1];
      j = 0;
    }

    for (var pl = rule.length; j < pl; j++) {
      var prop = rule[j];
      propStr +=
        prop[0] + ":" + prop[1] + (prop[2] ? " !important" : "") + ";\n";
    }

    // Insert CSS Rule
    styleSheet.insertRule(
      selector + "{" + propStr + "}",
      styleSheet.cssRules.length,
    );
  }
}
```

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

| Specification |
| --- |
| CSS Object Model (CSSOM) # dom-cssstylesheet-insertrule |

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

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

See also
--------

* `CSSStyleSheet.deleteRule` (en-US)
* Cross-Browser CSS-rules ordering (CSS1)
* Quirksmode - CSS


Performance.timing - Web APIs

Performance.timing
==================

摘要
--

**`Performance.timing`** 是唯讀的屬性，傳回的 `PerformanceTiming` (en-US) 物件當中包含了效能與時間延遲相關的資訊。

語法
--
```

timingInfo = performance.timing;
```

規格
--

因為 Navigation Timing 規範已被棄用，此特性不再有望成為標準。請使用 `PerformanceNavigationTiming` (en-US) 介面代替。

瀏覽器支援狀況
-------

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

參照
--

* 屬於 `Performance` (en-US) 界面的一部份


FileReader.error - Web APIs

FileReader.error
================

總覽
--

回傳讀取檔案時發生的錯誤。

語法
--
```

var error = instanceOfFileReader.error
```

Value
-----

A `DOMError` (en-US)

規格
--

| Specification |
| --- |
| File API # dom-filereader-error |

瀏覽器相容性
------

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

閱讀更多
----

* `FileReader`