События касаний (тач-события) - Интерфейсы веб API

События касаний (тач-события)
=============================

Чтобы предоставить качественную поддержку пользовательского интерфейса, связанного с касаниями, тач-события предлагают возможность интерпретировать действия пальца (или стилуса) на сенсорных экранах или трекпадах.

Интерфейсы событий касания - это относительно низкоуровневые API, которые можно использовать для поддержки приложений со специфическими мультитач-взаимодействиями, например жестом двумя пальцами. Мультитач взаимодействие запускается, когда палец (или стилус) впервые касается контактной поверхности. Другие пальцы могут следом коснуться поверхности и, если нужно, перемещаться по ней. Взаимодействие считается завершённым, когда пальцы с поверхности убираются. Во время взаимодействия, события касания срабатывают на начальном этапе (первое прикосновение), этапе перемещения по поверхности, и завершающем этапе (когда пальцы убираются с поверхности)..

События касаний подобны событиям мыши за исключением того, что они поддерживают несколько одновременных касаний в разных местах сенсорной поверхности. Интерфейс `TouchEvent` содержит все активные в данный момент точки прикосновения. Интерфейс `Touch`, который представляет одну точку касания, включает такую информацию, как позиция точки касания относительно области видимости браузера.

Определения
-----------

Поверхность (Surface)

Чувствительная к касаниям поверхность. Это может быть экран или трекпад.

Точка касания (Touch point)

Точка контакта с поверхностью. Это может быть палец (или локоть, ухо, нос, что угодно, но обычно это палец) или стилус.

Интерфейсы
----------

`TouchEvent`

Представляет событие, происходящее при изменении состояния касания поверхности.

`Touch`

Представляет одну точку контакта пользователя с сенсорной поверхностью.

`TouchList`

Представляет группу касаний; это используется, если пользователь, например, касается поверхности несколькими пальцами одновременно.

Пример
------

В этом примере отслеживаются несколько касаний одновременно, позволяя пользователю рисовать в `<canvas>` несколькими пальцами одновременно. Это будет работать лишь в браузере, который поддерживает touch-события.

**Примечание:** В тексте ниже для описания контакта с поверхностью используется понятие "палец", но это также может быть стилус или другой способ контакта.

### Создание canvas

```html
<canvas id="canvas" width="600" height="600" style="border:solid black 1px;">
  Ваш браузер не поддерживает элемент canvas.
</canvas>
<br />
Log:
<pre id="log" style="border: 1px solid #ccc;"></pre>
```

### Добавление обработчиков событий

После загрузки страницы будет вызвана функция `startup()`, показанная ниже

```js
function startup() {
  var el = document.getElementById("canvas");
  el.addEventListener("touchstart", handleStart, false);
  el.addEventListener("touchend", handleEnd, false);
  el.addEventListener("touchcancel", handleCancel, false);
  el.addEventListener("touchmove", handleMove, false);
}
```

document.addEventListener("DOMContentLoaded", startup);

Данная функция просто добавляет обработчики событий для элемента `<canvas>`, чтобы мы могли обрабатывать события касания по мере их возникновения

#### Отслеживание новых касаний

Рассмотрим касания в действии.

```js
var ongoingTouches = [];
```

Когда возникает событие `touchstart (en-US)`, свидетельствующее о новом касании к поверхности, вызывается приведённая ниже функция `handleStart()`.

```js
function handleStart(evt) {
  evt.preventDefault();
  console.log("touchstart.");
  var el = document.getElementById("canvas");
  var ctx = el.getContext("2d");
  var touches = evt.changedTouches;

  for (var i = 0; i < touches.length; i++) {
    console.log("touchstart:" + i + "...");
    ongoingTouches.push(copyTouch(touches[i]));
    var color = colorForTouch(touches[i]);
    ctx.beginPath();
    ctx.arc(touches[i].pageX, touches[i].pageY, 4, 0, 2 \* Math.PI, false); // a circle at the start
    ctx.fillStyle = color;
    ctx.fill();
    console.log("touchstart:" + i + ".");
  }
}
```

Она вызывает `event.preventDefault()` для того, чтобы предотвратить обработку браузером события касания (это также предотвращает обработку события мыши). Затем мы получаем контекст и извлекаем список изменённых точек касаний из свойства `TouchEvent.changedTouches` данного события.

После этого мы перебираем все объекты `Touch` в списке, помещая их в массив активных точек касания и рисуя начальную точку в виде маленького кружка; мы используем линию толщиной 4 пикселя, поэтому получим аккуратный круг радиусом 4 пикселя.

#### Рисование движением

Каждый раз, когда двигается один или несколько пальцев, срабатывает событие `touchmove (en-US)`, в результате чего вызывается наша функция `handleMove()`.В этом примере данная функция ответственна за обновление данных о касании и рисование линии от предыдущей до текущей точки касания.

```js
function handleMove(evt) {
  evt.preventDefault();
  var el = document.getElementById("canvas");
  var ctx = el.getContext("2d");
  var touches = evt.changedTouches;

  for (var i = 0; i < touches.length; i++) {
    var color = colorForTouch(touches[i]);
    var idx = ongoingTouchIndexById(touches[i].identifier);

    if (idx >= 0) {
      console.log("continuing touch " + idx);
      ctx.beginPath();
      console.log(
        "ctx.moveTo(" +
          ongoingTouches[idx].pageX +
          ", " +
          ongoingTouches[idx].pageY +
          ");",
      );
      ctx.moveTo(ongoingTouches[idx].pageX, ongoingTouches[idx].pageY);
      console.log(
        "ctx.lineTo(" + touches[i].pageX + ", " + touches[i].pageY + ");",
      );
      ctx.lineTo(touches[i].pageX, touches[i].pageY);
      ctx.lineWidth = 4;
      ctx.strokeStyle = color;
      ctx.stroke();

      ongoingTouches.splice(idx, 1, copyTouch(touches[i])); // swap in the new touch record
      console.log(".");
    } else {
      console.log("can't figure out which touch to continue");
    }
  }
}
```

Функция также перебирает изменённые касания, ищет в нашем массиве данных о касаниях предыдущие данные о каждом касании для определения начальной точки каждого отрезка линии, который должен быть нарисован с помощью касания. Это реализовано путём отслеживания свойства `Touch.identifier` (en-US) каждого касания. Это свойство является уникальным числом для каждого касания, и остаётся неизменным на протяжении всего времени контакта пальца с экраном.

Это позволяет нам получать координаты предыдущей позиции каждого касания и использовать подходящий метод "canvas-контекста" для рисования отрезка линии, соединяющего начало и конец.

После рисования линии, мы вызываем `Array.splice()`, чтобы в массиве `ongoingTouches` заменить предыдущие данные о точке касания на текущие.

#### Обработка завершения касания

Когда пользователь убирает палец с сенсорной поверхности, срабатывает событие `touchend` (en-US). Мы обрабатываем его, вызывая функцию `handleEnd()`, которая представлена ниже. Её задача - рисовать последний отрезок линии для каждого касания, которое завершилось, и удалять точку касания из текущего списка касаний.

```js
function handleEnd(evt) {
  evt.preventDefault();
  log("touchend");
  var el = document.getElementById("canvas");
  var ctx = el.getContext("2d");
  var touches = evt.changedTouches;

  for (var i = 0; i < touches.length; i++) {
    var color = colorForTouch(touches[i]);
    var idx = ongoingTouchIndexById(touches[i].identifier);

    if (idx >= 0) {
      ctx.lineWidth = 4;
      ctx.fillStyle = color;
      ctx.beginPath();
      ctx.moveTo(ongoingTouches[idx].pageX, ongoingTouches[idx].pageY);
      ctx.lineTo(touches[i].pageX, touches[i].pageY);
      ctx.fillRect(touches[i].pageX - 4, touches[i].pageY - 4, 8, 8); // and a square at the end
      ongoingTouches.splice(idx, 1); // remove it; we're done
    } else {
      console.log("can't figure out which touch to end");
    }
  }
}
```

Она очень похожа на предыдущую функцию; единственное отличие заключается в том, что,что теперь мы рисуем маленький квадрат, чтобы обозначить конец, и в том, что когда мы мы вызываем `Array.splice()`, мы просто удаляем старую запись из текущего списка касаний без добавления обновлённой информации. В результате мы прекращаем отслеживать эту точку касания.

#### Обработка отменённых касаний

Если палец пользователя перемещается в интерфейс браузера или прикосновение должно быть отменено, отправляется событие `touchcancel` (en-US), и мы вызываем функцию `handleCancel()`, приведённую ниже.

```js
function handleCancel(evt) {
  evt.preventDefault();
  console.log("touchcancel.");
  var touches = evt.changedTouches;

  for (var i = 0; i < touches.length; i++) {
    var idx = ongoingTouchIndexById(touches[i].identifier);
    ongoingTouches.splice(idx, 1); // remove it; we're done
  }
}
```

Поскольку идея состоит в том, чтобы немедленно прервать касание, мы просто удаляем его из текущего списка касаний без рисования завершающего отрезка линии.

### Удобные функции

Этот пример использует две удобные функции, которые следует кратко рассмотреть, чтобы сделать остальную часть кода более понятной.

#### Выбор цвета для каждого касания

Чтобы рисунок каждого касания выглядел по-разному, используется функция `colorForTouch()`, в которой цвета выбираются на основе уникального идентификатора касаний. Этот идентификатор является скрытым числом, но мы, по крайней мере, можем полагаться на то, что у каждого активного на данный момент касания он уникальный.

```js
function colorForTouch(touch) {
  var r = touch.identifier % 16;
  var g = Math.floor(touch.identifier / 3) % 16;
  var b = Math.floor(touch.identifier / 7) % 16;
  r = r.toString(16); // make it a hex digit
  g = g.toString(16); // make it a hex digit
  b = b.toString(16); // make it a hex digit
  var color = "#" + r + g + b;
  console.log(
    "color for touch with identifier " + touch.identifier + " = " + color,
  );
  return color;
}
```

Результатом этой функции является строка, которую можно использовать при вызове `<canvas>`-функций для задания цвета рисования. Например, для значения `Touch.identifier` (en-US), равного 10, результатом будет "#a31".

#### Копирование объекта касания

Некоторые браузеры (например, мобильный Safari) повторно используют объекты касания в разных событиях, поэтому лучше копировать только важные свойства, а не ссылаться на весь объект.

```js
function copyTouch({ identifier, pageX, pageY }) {
  return { identifier, pageX, pageY };
}
```

#### Поиск текущего касания

Приведённая ниже функция `ongoingTouchIndexById()` сканирует весь массив `ongoingTouches`, чтобы найти касание, соответствующее данному идентификатору, после чего возвращает в массив индекс этого касания.

```js
function ongoingTouchIndexById(idToFind) {
  for (var i = 0; i < ongoingTouches.length; i++) {
    var id = ongoingTouches[i].identifier;

    if (id == idToFind) {
      return i;
    }
  }
  return -1; // not found
}
```

#### Отображение происходящего

```js
function log(msg) {
  var p = document.getElementById("log");
  p.innerHTML = msg + "\n" + p.innerHTML;
}
```

Если ваш браузер поддерживает это, вы можете посмотреть живой пример.

Пример sFiddle

Дополнительные советы
---------------------

Этот раздел даёт дополнительные советы о том, как обрабатывать события касаний в ваших веб-приложениях.

### Обработка кликов

Поскольку вызов `preventDefault()` для события `touchstart (en-US)` или первого события из серии событий `touchmove` (en-US) предотвращает запуск соответствующих событий мыши, более распространена практика вызова `preventDefault()` именно для события `touchmove`, а не `touchstart`. Таким образом, события мыши всё ещё будут вызываться, а такие элементы, как ссылки, будут продолжать работать. В качестве альтернативы, в некоторых фреймворках для этой же цели события касаний дублируются событиями мыши.

Данный пример очень упрощён и может привести к странному поведению. Он уместен исключительно как учебный пример.

```js
function onTouch(evt) {
  evt.preventDefault();
  if (
    evt.touches.length > 1 ||
    (evt.type == "touchend" && evt.touches.length > 0)
  )
    return;

  var newEvt = document.createEvent("MouseEvents");
  var type = null;
  var touch = null;

  switch (evt.type) {
    case "touchstart":
      type = "mousedown";
      touch = evt.changedTouches[0];
      break;
    case "touchmove":
      type = "mousemove";
      touch = evt.changedTouches[0];
      break;
    case "touchend":
      type = "mouseup";
      touch = evt.changedTouches[0];
      break;
  }

  newEvt.initMouseEvent(
    type,
    true,
    true,
    evt.originalTarget.ownerDocument.defaultView,
    0,
    touch.screenX,
    touch.screenY,
    touch.clientX,
    touch.clientY,
    evt.ctrlKey,
    evt.altKey,
    evt.shiftKey,
    evt.metaKey,
    0,
    null,
  );
  evt.originalTarget.dispatchEvent(newEvt);
}
```

### Вызов preventDefault() только при втором касании

Один из способов запретить использовать на странице `pinchZoom` (зум с помощью щипка), – вызвать `preventDefault()` для второго касания, когда одно касание уже активно. Такое поведение плохо прописано в спецификации событий касаний и приводит к разному поведению в разных браузерах. Например, iOS предотвратит зум, но всё ещё будет позволять перетаскивание (panning) двумя пальцами; в Android, наоборот, можно будет осуществлять перетаскивание (panning), но не зум; Opera и Firefox на данный момент предотвращают и перетаскивание (panning) и зум. На данный момент для запрета использования зума рекомендуется полагаться не на какое-то конкретное поведение, а на meta-данные для "viewport".

Спецификация
------------

| Specification |
| --- |
| Touch Events |

Совместимость с браузерами
--------------------------

### Touch

События касаний обычно доступны на устройствах с сенсорными экранами, но многие браузеры делают API событий касаний недоступными на всех компьютерах, даже имеющих сенсорный экран.

Причина этого заключается в том, что некоторые веб-сайты используют поддержку данного API в качестве показателя того, что браузер запущен на мобильном устройстве. Если API событий касания доступен, значит эти сайты будут предполагать работу с мобильного устройства и предоставлять соответствующее содержимое, оптимизированное для мобильных устройств. Это может существенно усложнить работу для пользователей десктопов с сенсорными экранами.

Для поддержки и касаний и мыши на всех типах устройств, используйте вместо этого события указателя

### api.Touch

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

### api.TouchEvent

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

### api.TouchList

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

### Firefox, события касаний и многопроцессность (e10s)

В Firefox события касания отключены, когда отключён e10s (электролиз; многопроцессорный Firefox). e10s включён по умолчанию в Firefox, но может в конечном итоге отключаться в определённых ситуациях, например, когда установлены определённые инструменты специальных возможностей или надстройки Firefox, для работы которых требуется отключение e10s. Это означает, что даже на настольном компьютере / ноутбуке с сенсорным экраном сенсорные события не будут включены.

Вы можете проверить, отключён ли e10s, перейдя в `about:support` и посмотрев на запись «Многопроцессорная Windows» в разделе «Основы приложения». 1/1 означает, что он включён, 0/1 означает отключён.

Если вы хотите принудительно включить e10s - чтобы явно повторно включить поддержку сенсорных событий - вам нужно перейти к `about:config` и создать новое логическое предпочтение `browser.tabs.remote.force-enable`. Установите значение `true`, перезапустите браузер, и e10s будет включён независимо от любых других настроек.


Интерфейс RTCPeerConnection - Интерфейсы веб API

Интерфейс RTCPeerConnection
===========================

Интерфейс **`RTCPeerConnection`** представляет соединение WebRTC между локальным пиром (участником соединения) на локальном компьютере и удалённым пиром на удалённом компьютере. Он предоставляет методы для соединения с удалённым участником соединения, обслуживания, мониторинга и закрытия соединения.

EventTarget

RTCPeerConnection### Устаревший метод

Метод ниже, является устаревшим и не будет в дальнейшем реализован в современных браузерах.

`RTCPeerConnection.createDTMFSender()`

Создаёт новый объект типа `RTCDTMFSender` (en-US), связанный с определённым объектом `MediaStreamTrack`, который сможет отправить объект сигнализации DTMF (en-US) поверх соединения..

События
-------

Для обработки событий используется функция добавления обработчика события `addEventListener()` или используется стандартное свойство интерфейса по схеме `onимясобытия` (префикс **on** к которому добавляется имя события прописными буквами) для установки обработчика события.

`connectionstatechange` (en-US)

 Событие объекта `RTCPeerConnection` возникает, когда общий статус объекта соединения `RTCPeerConnection` изменился.
 Так же, доступно через свойство установки обработчика события `onconnectionstatechange` (en-US).

`datachannel` (en-US)

 Событие объекта `RTCPeerConnection` возникает, когда удалённый пир (участник соединения) добавляет объект данных `RTCDataChannel` (en-US) в текущее соединение.
 Так же, доступно через свойство установки обработчика события `ondatachannel` (en-US).

`icecandidate`

 Событие объекта `RTCPeerConnection` возникает, когда специальный объект ICE кандидата (RTCIceCandidate (en-US)) сгенерирован `RTCPeerConnection` и готов для передачи удалённому пиру по каналу сигнализации.Сам сгенерированный объект кандидата передаётся в параметр вызванного обработчика.
 Так же, доступно через свойство установки обработчика события `onicecandidate` (en-US).

`icecandidateerror` (en-US)

 Событие типа ошибки `RTCPeerConnectionIceErrorEvent` (en-US) , возникает на объекте соединения при генерации ICE кандидата (RTCIceCandidate (en-US)), если при этом возникла ошибка. Свойства объекта ошибки, возвращаемого в обработчик, описывают подробности ошибки.
 Так же, доступно через свойство установки обработчика события `onicecandidateerror` (en-US).

`iceconnectionstatechange` (en-US)

 Событие объекта `RTCPeerConnection` возникает при изменении статуса ICE соединения. К примеру, ICE (en-US) соединение разорвано.
 Так же, доступно через свойство установки обработчика события`oniceconnectionstatechange` (en-US) .

`icegatheringstatechange` (en-US)

 Событие объекта `RTCPeerConnection,` возникает, когда статус сборки, представленный классом `iceGatheringState` (en-US), изменяется. Это указывает на то, что : согласование соединения ICE ещё не началось (статус равен значению "`new`"); согласование соединения ICE началось (статус равен значению "`gathering`"); согласование ICE соединения завершено (статус равен значению "`complete`").
 Так же, доступно через свойство установки обработчика `onicegatheringstatechange` (en-US) .

`isolationchange`

 Событие объекта `RTCPeerConnection` возникает, когда свойство `isolated` на одном из объектов `MediaStreamTrack` , связанного с соединением изменяет своё значение. Объект трека является изолированным `isolated`, если его содержимое не может быть доступно содержащему его документу, по причине невозможности аутентификации, или объект трека прибыл не из источника происхождения страницы.
 Так же, доступно через свойство установки обработчика `onisolationchange`.

`negotiationneeded` (en-US)

 Событие объекта `RTCPeerConnection` возникает, когда необходимо запустить согласование (пересогласование) ICE соединения; может произойти при первом открытии соединения , или при необходимости принятия изменений условий сети. Получатель должен ответить, создав предложение и отправив его другому партнёру.
 Так же, доступно через свойство установки обработчика `onnegotiationneeded` (en-US).

`signalingstatechange` (en-US)

 Событие `signalingstatechange` возникает, когда статус сигнализации ICE соединения изменился..
 Так же, доступно через свойство установки обработчика `onsignalingstatechange` (en-US).

`track` (en-US)

 Событие `track` возникает после того, как новый объект трека был добавлен в один из объектов интерфейса `RTCRtpReceiver` (en-US) , которые входят в состав соединения.
 Так же, доступно через свойство установки обработчика `ontrack` (en-US) .

### Устаревшие события

`addstream` (en-US)

 Возникает, когда новый объект `MediaStream` был добавлен в соединение. Вместо наблюдения за этим устаревшим событием, разработчику следует наблюдать за каждым событием `track` (en-US), возникающим при добавлении в соединение объекта `MediaStreamTrack`..
 Установка обработчика возможна через свойство `onaddstream` (en-US) .

`identityresult`

 В старой версии спецификации WebRTC это событие использовалось для указания доступности подтверждения идентичности. Теперь, следует ждать возвращение промиса от `peerIdentity` (en-US) для подтверждения личности.
 Установка обработчика возможна через свойство `onidentityresult`.

`idpassertionerror`

 В старой версии спецификации WebRTC это событие использовалось для определения возникшей ошибки при попытке генерации подтверждения идентичности. Теперь, нужно ожидать результата работы промиса, возвращаемого методом доступа `peerIdentity` (en-US) , передающий в метод перехвата ошибок промиса, возникшую ошибку.
 Установка обработчика возможна через свойство `onidpinsertionerror`..

`idpvalidationerror`

 В старой версии спецификации WebRTC это событие использовалось для определения того, что ошибка возникла при попытке подтверждения идентичности. Теперь, следует ожидать результат работы промиса, возвращаемого методом доступа `peerIdentity` (en-US), для перехвата ошибки в соответствующем методе.
 Установка обработчика возможна через свойство `onpeerdentity` .

`peeridentity`

В старой версии спецификации WebRTC это событие использовалось для доставки полученной идентичности. Теперь, нужно ожидать результата работы промиса, возвращаемого методом доступа `peerIdentity` (en-US), для получения идентичности.

`removestream` (en-US)

 Возникает на объекте `RTCPeerConnection`, когда объект `MediaStream` удаляется из соединения. Теперь, необходимо наблюдать за событиями `removetrack` (en-US) на каждом потоке, входящем в состав объекта соединения `RTCPeerConnection`.
 Установка обработчика возможна через свойство `onaddstream` (en-US) .

Константы
---------

### Перечисление RTCBundlePolicy

Перечисление `RTCBundlePolicy` (политика сборки пакетов) определяет строковые константы, которые используются для запроса определённой политики при сборке ICE кандидатов, в случае, если удалённый участник соединения (удалённая точка) не совместим со стандартом SDP BUNDLE standard для объединения нескольких медиапотоков в один транспортный пакет.

**Примечание:** В технических терминах BUNDLE (пакет) позволяет всем медиапотокам между двумя пирами проходить через один 5 - ти элементный кортеж (тип транспортного протокола передачи сообщений при установки TCP, UDP, и ICMP соединений, состоящий из пяти элементов анализа данных). То есть, с одного IP-адреса и порта на одном узле на один IP-адрес и порт на другом узле с использованием одного и того же транспортного протокола.

| Константа | Описание |
| --- | --- |
| `"balanced"` | Сбалансированный. Агент ICE изначально создаёт по одному объекту `RTCDtlsTransport` (en-US) для каждого типа добавляемого контента: аудио, видео и каналов данных. Если удалённая конечная точка не опознает пакеты, то каждый из этих DTLS транспортов обрабатывает все коммуникации для одного типа данных. |
| `"max-compat"` | Максимально совместимый. Агент ICE изначально создаёт один объект `RTCDtlsTransport` (en-US) для каждой медиа-дорожки и отдельный для каналов данных. Если удалённая точка не поддерживает опознавание пакета, все согласовывается на этих отдельных DTLS транспортах |
| `"max-bundle"` | Максимальный пакет. Агент ICE изначально создаёт только один объект `RTCDtlsTransport` (en-US) для переноса всех данных RTCPeerConnection. Если удалённая точка не поддерживает опознавание пакета, то согласовывается только одна дорожка, а остальные игнорируются. |

### Перечисление RTCIceConnectionState

Перечисление `RTCIceConnectionState` определяет строковые константы, использующиеся для описания текущего состояния ICE агента и его соединения с ICE сервером STUN (en-US) или TURN (en-US) .

| Константа | Описание |
| --- | --- |
| `"new"` | ICE агент собирает адреса или ожидает получения удалённых кандидатов от вызова метода `RTCPeerConnection.addIceCandidate()` (en-US). Или все сразу. |
| `"checking"` | ICE агент получил один или несколько удалённых кандидатов и проверяет парность локального и удалённого кандидатов относительно друг друга, пытаясь обнаружить совместимости. Но ещё не обнаружил пару, соответствующую устанавливаемому удалённому соединению.Не исключено, что сборка кандидатов продолжиться. |
| `"connected"` | Совместимая парность локального и удалённого кандидатов найдена для всех компонентов соединения, и соединение было установлено. Не исключено продолжение сборки и проверки кандидатов в процессе соединения, для наилучший совместимости. |
| `"completed"` | Агент ICE завершил сбор кандидатов, проверил все пары относительно друг друга, и установил все соединения для всех компонентов. |
| `"failed"` | Агент ICE проверил все пары кандидатов между собой и не нашёл совместимых сопоставлений для всех компонентов соединения. Или не нашёл совместимых соединений для некоторых компонентов. |
| `"disconnected"` | Проверяет, что компоненты все ещё подключены, хотя бы для одного объекта `RTCPeerConnection`. Это менее строгий тест, чем `"failed"`, и он может периодически запускаться и разрешаться спонтанно в менее надёжных сетях, или во время временного отключения. Когда проблема исчезнет, соединение может вернуться в состояние `"connected".` |
| `"closed"` | ICE агент закрыл соединение для объекта `RTCPeerConnection` и больше не обрабатывает запросы. |

### Перечисление RTCIceGatheringState

Перечисление `RTCIceGatheringState` определяет строковые константы, которые описывают текущий статус ICE сборки, возвращаемый свойством `RTCPeerConnection.iceGatheringState` (en-US). Для определения изменения этого свойства можно подписаться на событие `icegatheringstatechange`.

| Константы | Описание |
| --- | --- |
| `"new"` | Соединение только что создано, и ещё не имело сетевой активности. |
| `"gathering"` | Агент ICE находиться в процессе сборки кандидатов соединения. |
| `"complete"` | Агент ICE завершил сборку кандидатов. Если произойдёт, что-то (например, добавление нового ICE сервера), для чего потребуется новая сборка кандидатов, статус переключиться в значение "`gathering`" и начнётся пересборка кандидатов. |

### Перечисление RTCIceTransportPolicy

Перечисление `RTCIceTransportPolicy` определяет строковые константы, использующиеся для ограничения политик передачи ICE кандидатов, учитывающихся во время процесса соединения..

| Константа | Описание |
| --- | --- |
| `"all"` | Все ICE кандидаты будут рассмотрены. |
| `"public"` | Будут рассматриваться ICE кандидаты, только имеющие публичные IP адреса. *Удалён в спецификации от 13 мая 2016 (working draft).* |
| `"relay"` | Будут рассматриваться ICE кандидаты, только с переданными IP адресами через TURN сервер. |

### Перечисление RTCPeerConnectionState

Перечисление `RTCPeerConnectionState` определяет строковые константы, описывающие статус `RTCPeerConnection`. Эти значения возвращаются свойством (методом доступа) `connectionState` . Этот статус представляет собирательный статус всех ICE передач (которые имеют тип `RTCIceTransport` (en-US) или `RTCDtlsTransport` (en-US)) , использующиеся соединением.

| Константа | Описание |
| --- | --- |
| `"new"` | Новый. По меньшей мере один из объектов ICE передачи (`RTCIceTransport` (en-US) или `RTCDtlsTransport` (en-US) ) в соединении находиться в статусе `"new"` и ни один из них не находиться в одном из перечисленных статусов : `"connecting"`, `"checking"`, `"failed"`, или `"disconnected"`, или все объекты передач соединения находятся в статусе `"closed"`. |
| `"connecting"` | В процессе соединения. Один или несколько объектов ICE передачи находятся в процессе установки соединения. Т.е. их свойство `RTCIceConnectionState` либо имеет значение `"checking"` , либо `"connected"`, и ни один из объектов передачи не находиться в статусе `"failed"` . **<<< Make this a link once I know where that will be documented** |
| `"connected"` | Соединён. Каждый объект ICE передачи, использующийся соединением либо используется (имеет статус `"connected"` или `"completed"`) , либо закрыт (имеет статус `"closed"`); кроме того, по крайней мере один объект передачи имеет статус либо `"connected"` , либо `"completed"`. |
| `"disconnected"` | Разъединён. По меньшей мере один из объектов ICE передачи в соединении имеет статус `"disconnected"` и ни один из объекто передачи не находиться в статусе : `"failed"`, `"connecting"`, или `"checking"`. |
| `"failed"` | Неудачно. Один или несколько объектов передачи могут находиться в статусе `"failed"`. |
| `"closed"` | Закрыто. Соединение `RTCPeerConnection` закрыто.Ранее входило в значения перечисления `RTCSignalingState` (и поэтому может быть найдено в свойстве `signalingState` (en-US)) до 13 мая, 2016. |

### Перечисление RTCRtcpMuxPolicy

Перечисление `RTCRtcpMuxPolicy` содержит строковые константы, определяющие , что собираемые кандидаты должны иметь поддержку немультиплексированного RTCP . **<<<add a link to info about multiplexed RTCP.**

| Константа | Описание |
| --- | --- |
| `"negotiate"` | Instructs the ICE agent to gather both RTP (en-US) and RTCP (en-US) candidates. If the remote peer can multiplex RTCP, then RTCP candidates are multiplexed atop the corresponding RTP candidates. Otherwise, both the RTP and RTCP candidates are returned, separately. |
| `"require"` | Tells the ICE agent to gather ICE candidates for only RTP, and to multiplex RTCP atop them. If the remote peer doesn't support RTCP multiplexing, then session negotiation fails. |

### Перечисление RTCSignalingState

Перечисление `RTCSignalingState` определяет возможные значения состояния сигнализирования `RTCPeerConnection.signalingState` (en-US), указывая в каком месте процесса сигнализации в настоящее время находиться обмен предложением или ответом.

| Константа | Описание |
| --- | --- |
| `"stable"` |
 Стабильно. Текущего процесса обмена предложения/ответ не происходит.
 Это может означать, что объект соединения
 `RTCPeerConnection` новый, и в этом случае
 объекты описания
 `localDescription` (en-US)
 и
 `remoteDescription` (en-US)
 имеют значения `null`; Так же, может означать, что
 согласование завершено и соединение успешно установлено.
  |
| `"have-local-offer"` |
 Имеет локальное предложение. Локальный пир вызвал метод
 `RTCPeerConnection.setLocalDescription()` (en-US),
 передав в него объект описания SDP , представляющий предложение (обычно,
 созданного вызовом метода
 `RTCPeerConnection.createOffer()` (en-US)), и это
 предложение было успешно применено.
  |
| `"have-remote-offer"` |
 Имеет удалённое предложение. Удалённый пир создал предложение,
 использовал сервер сигнализации для передачи этого предложения
 локальному пользователю, которое было установлено им в параметр, через
 вызов метода
 `RTCPeerConnection.setRemoteDescription()` (en-US).
  |
| `"have-local-pranswer"` |
 Имеет локальный предварительный ответ. Предложение удалённого пира было
 применено, и ответ был создан (обычно, через вызов метода
 `RTCPeerConnection.createAnswer()` (en-US)) и
 использовано в параметре метода установки локального дескриптора
 `RTCPeerConnection.setLocalDescription()` (en-US).
 Этот предварительный ответ описывает поддерживаемые медиа форматы и тому
 подобное. Но он не имееет включённых в него полного набора ICE
 кандидатов. Позже, дополнительные кандидаты будут доставлены отдельно.
  |
| `"have-remote-pranswer"` |
 Имеет предварительный удалённый ответ. Предварительный удалённый ответ
 был получен и успешно применён в ответ на предложение, отправленное
 ранее и установленное методом `setLocalDescription()`.
  |
| `"closed"` | Закрыто. Соединение закрыто.

**Примечание :** Это значение перенесено в перечисление
 `RTCPeerConnectionState`
 в черновике от 13 мая 2016, поскольку оно отражает статус соединения
 `RTCPeerConnection`, а не статус сигнализации. Теперь,
 для проверки закрытия соединения нужно проверять статус
 `connectionState`
 на значение `"closed"` .

 |

Спецификации
------------

| Specification |
| --- |
| WebRTC: Real-Time Communication in Browsers # interface-definition |

Совместимость с браузерами
--------------------------

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

Смотрите также
--------------

* https://github.com/jesup/nightly-gupshup/blob/master/static/js/chat.js
* http://www.html5rocks.com/en/tutorials/webrtc/basics/#toc-simple
* TutorRoom: Node.js HTML5 video capture, peer-to-peer video and filesharing application (source on GitHub)


HTMLVideoElement - Интерфейсы веб API

HTMLVideoElement
================

**`HTMLVideoElement`** интерфейс предоставляет специальные свойства и методы для манипулирования видео объектов. Он также наследует свойства и методы `HTMLMediaElement` и `HTMLElement`.

Список поддерживаемых форматов медиа варьируются из одного браузера в другой. Вы должны либо предоставить ваше видео в одном формате которые поддерживаются всеми актуальными браузерами, или предоставить множественные источники видео в достаточно разных форматах чтобы все браузеры которые вам нужны поддерживали их.

Свойства
--------

*Inherits properties from its parent,* *`HTMLMediaElement`, and* *`HTMLElement`.*

`HTMLVideoElement.height` (en-US)

Is a `DOMString` that reflects the `height` HTML attribute, which specifies the height of the display area, in CSS pixels.

`HTMLVideoElement.poster`

Is a `DOMString` that reflects the `poster` HTML attribute, which specifies an image to show while no video data is available.

`HTMLVideoElement.videoHeight` (en-US) Только для чтения

Returns an `unsigned long` containing the intrinsic height of the resource in CSS pixels, taking into account the dimensions, aspect ratio, clean aperture, resolution, and so forth, as defined for the format used by the resource. If the element's ready state is `HAVE_NOTHING`, the value is `0`.

`HTMLVideoElement.videoWidth` (en-US) Только для чтения

Returns an `unsigned long` containing the intrinsic width of the resource in CSS pixels, taking into account the dimensions, aspect ratio, clean aperture, resolution, and so forth, as defined for the format used by the resource. If the element's ready state is `HAVE_NOTHING`, the value is `0`.

`HTMLVideoElement.width` (en-US)

Is a `DOMString` that reflects the `width` HTML attribute, which specifies the width of the display area, in CSS pixels.

### Gecko-специфичные свойства

`HTMLVideoElement.mozParsedFrames` Только для чтения
Non-standard

Returns an `unsigned long` with the count of video frames that have been parsed from the media resource.

`HTMLVideoElement.mozDecodedFrames` Только для чтения
Non-standard

Returns an `unsigned long` with the count of parsed video frames that have been decoded into images.

`HTMLVideoElement.mozPresentedFrames` Только для чтения
Non-standard

Returns an `unsigned long` with the count of decoded frames that have been presented to the rendering pipeline for painting.

`HTMLVideoElement.mozPaintedFrames` Только для чтения
Non-standard

Returns an `unsigned long` with the count of presented frames which were painted on the screen.

`HTMLVideoElement.mozFrameDelay` Только для чтения
Non-standard

Returns an `double` with the time which the last painted video frame was late by, in seconds.

`HTMLVideoElement.mozHasAudio` Только для чтения
Non-standard

Returns a `Boolean` (en-US) indicating if there is some audio associated with the video.

Методы
------

*Inherits methods from its parent,* *`HTMLMediaElement`, and* *`HTMLElement`.*

`HTMLVideoElement.getVideoPlaybackQuality()` (en-US)
Экспериментальная возможность

Returns a `VideoPlaybackQuality` (en-US) objects that contains the current playback metrics.

Спецификации
------------

| Specification |
| --- |
| HTML Standard # htmlvideoelement |

Совместимость с браузерами
--------------------------

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

Смотрите также
--------------

* HTML element implementing this interface: `<video>`.
* Demo of video paint statistics
* Supported media formats (en-US)


Intersection Observer API - Интерфейсы веб API

Intersection Observer API
=========================

Intersection Observer API позволяет веб-приложениям асинхронно следить за изменением пересечения элемента с его родителем или областью видимости документа viewport.

Исторически обнаружение видимости отдельного элемента или видимости двух элементов по отношению друг к другу было непростой задачей. Варианты решения этой задачи были ненадёжными и замедляли работу браузера. К несчастью, по мере того как веб "взрослел", потребность в решении этой проблемы только росла по многим причинам, таким как:

* Отложенная загрузка изображений или другого контента по мере прокрутки страницы.
* Реализация веб-сайтов с "бесконечным скроллом", где контент подгружается по мере того как страница прокручивается вниз, и пользователю не нужно переключаться между страницами.
* Отчёт о видимости рекламы с целью посчитать доходы от неё.
* Принятие решения, запускать ли какой-то процесс или анимацию в зависимости от того, увидит пользователь результат или нет.

В прошлом реализация обнаружения пересечения элементов подразумевала использование обработчиков событий и циклов, вызывающих методы типа `Element.getBoundingClientRect()`, чтобы собрать необходимую информацию о каждом затронутом элементе. Поскольку весь этот код работает в основном потоке, возникают проблемы с производительностью.

Рассмотрим веб-страницу с бесконечным скроллом. На ней используется библиотека для управления периодически размещаемой по всей странице рекламой, повсюду анимированная графика, а также библиотека для отображения всплывающих окон. И все эти вещи используют свои собственные правила для обнаружения пересечений, и все они запущены в основном потоке. Автор сайта может даже не подозревать об этой проблеме, а также может не знать, как работают сторонние библиотеки изнутри. В то же время пользователь по ходу прокрутки страницы сталкивается с тем, что работа сайта замедляется постоянным срабатыванием обнаружения пересечения, что в итоге приводит к тому, что пользователь недоволен браузером, сайтом и своим компьютером.

Intersection Observer API даёт возможность зарегистрировать колбэк-функцию, которая выполнится при пересечении наблюдаемым элементом границ другого элемента (или области видимости документа viewport), либо при изменении величины пересечения на определённое значение. Таким образом, больше нет необходимости вычислять пересечение элементов в основном потоке, и браузер может оптимизировать эти процессы на своё усмотрение.

Observer API не позволит узнать точное число пикселей или определить конкретные пиксели в пересечении; однако, его использование покрывает наиболее частые сценарии вроде "Если элементы пересекаются на N%, сделай то-то".

Основные понятия
----------------

Intersection Observer API позволяет указать функцию, которая будет вызвана всякий раз для элемента (**target**) при пересечении его с областью видимости документа (по умолчанию) или заданным элементом (**root**).

В основном, используется отслеживание пересечения элемента с областью видимости (необходимо указать `null` в качестве корневого элемента).

Используете ли вы область видимости или другой элемент в качестве корневого, API работает одинаково, вызывая заданную вами колбэк-функцию, всякий раз, когда видимость целевого элемента изменяет так, что она пересекает в нужной степени корневой элемент.

Степень пересечения целевого и корневого элемента задаётся в диапазоне от 0.0 до 1.0, где 1.0 это полное пересечение целевого элемента границ корневого.

### Пример использования

Для начала с помощью конструктора нужно создать объект-наблюдатель, указать для него функцию для вызова и настройки отслеживания:

```js
var options = {
  root: document.querySelector("#scrollArea"),
  rootMargin: "0px",
  threshold: 1.0,
};
var callback = function (entries, observer) {
  /\* Content excerpted, show below \*/
};
var observer = new IntersectionObserver(callback, options);
```

Параметр threshold со значением 1.0 означает что функция будет вызвана при 100% пересечении объекта (за которым мы следим) с объектом root

### Настройки

root

Элемент который используется в качестве области просмотра для проверки видимости целевого элемента. Должен быть предком целевого элемента. По умолчанию используется область видимости браузера если не определён или имеет значение null.

rootMargin

Отступы вокруг root. Могут иметь значения как свойство css margin: "`10px 20px 30px 40px" (top, right, bottom, left).` Значения можно задавать в процентах. По умолчанию все параметры установлены в нули.

threshold

Число или массив чисел, указывающий, при каком проценте видимости целевого элемента должен сработать callback. Например, в этом случае callback функция будет вызываться при появлении в зоне видимости каждый 25% целевого элемента: [0, 0.25, 0.5, 0.75, 1]

#### Целевой элемент, который будет наблюдаться

После того, как вы создали наблюдателя, вам нужно дать ему целевой элемент для просмотра:

```js
var target = document.querySelector("#listItem");
observer.observe(target);
```

Всякий раз, когда цель достигает порогового значения, указанного для `IntersectionObserver`, вызывается колбэк-функция `callback`. Где `callback` получает список объектов `IntersectionObserverEntry` (en-US) и наблюдателя:

```js
var callback = function (entries, observer) {
  entries.forEach((entry) => {
    entry.time; // a DOMHightResTimeStamp indicating when the intersection occurred.
    entry.rootBounds; // a DOMRectReadOnly for the intersection observer's root.
    entry.boundingClientRect; // a DOMRectReadOnly for the intersection observer's target.
    entry.intersectionRect; // a DOMRectReadOnly for the visible portion of the intersection observer's target.
    entry.intersectionRatio; // the number for the ratio of the intersectionRect to the boundingClientRect.
    entry.target; // the Element whose intersection with the intersection root changed.
    entry.isIntersecting; // intersecting: true or false
  });
};
```

Обратите внимание, что колбэк-функция запускается в главном потоке и должна выполняться как можно быстрее, поэтому если что-то отнимает много времени, то используйте `Window.requestIdleCallback()`.

Также обратите внимание, что если вы указали опцию `root`, целевой элемент должен быть потомком корневого элемента.

Интерфейсы
----------

`IntersectionObserver`

Основной интерфейс для API Intersection Observer. Предоставляет методы для создания и управления observer, который может наблюдать любое количество целевых элементов для одной и той же конфигурации пересечения. Каждый observer может асинхронно наблюдать изменения в пересечении между одним или несколькими целевыми элементами и общим элементом-предком или с их верхним уровнем `Document`'s viewport. Предок или область просмотра упоминается как **root**.

`IntersectionObserverEntry` (en-US)

Описывает пересечение между целевым элементом и его корневым контейнером в определённый момент перехода. Объекты этого типа могут быть получены только двумя способами: в качестве входных данных для вашего колбэка IntersectionObserver или путём вызова `IntersectionObserver.takeRecords()` (en-US).

Спецификации
------------

| Specification |
| --- |
| Intersection Observer # intersection-observer-interface |

Совместимость с браузерами
--------------------------

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

Смотрите также
--------------

* Intersection Observer polyfill
* Timing element visibility with the Intersection Observer API
* `IntersectionObserver` and `IntersectionObserverEntry` (en-US)


Глобальная функция setInterval() - Интерфейсы веб API

Глобальная функция setInterval()
================================

**Примечание:** Эта возможность доступна в Web Workers

Метод **`setInterval()`** доступен из интерфейсов `Window` и `WorkerGlobalScope` (en-US). Он циклически вызывает функцию или участок кода с фиксированной паузой между каждым вызовом. Уникальный идентификатор intervalID, возвращаемый методом, позволяет впоследствии удалить запущенный **`setInterval`** c помощью `clearInterval()` (en-US).

Синтаксис
---------
```

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

### Параметры

`func`

`function` - функция, которая будет вызываться каждые `delay` миллисекунд. Ожидается, что функция не принимает параметры и ничего не возвращает.

`code`

Этот необязательный синтаксис позволяет вам включать строку вместо функции, которая компилируется и выполняется каждые `delay` миллисекунд. Однако такая форма не рекомендуется по тем же причинам, которые делают `eval()` (en-US) угрозой безопасности.

`delay`

Время в миллисекундах (одна тысячная секунды), на которое таймер выполнит задержку между вызовом функции. Если задано значение меньше 10, то будет использовано число 10. На самом деле задержка может быть больше чем указано, дополнительное объяснение приведено здесь: Reasons for delays longer than specified.

`param1, ..., paramN` Необязательный

Дополнительные параметры, передаваемые в функцию *func*.

**Примечание:** Передача дополнительных аргументов в `setInterval()` в первом синтаксисе не работает в Internet Explorer 9 и более ранних версиях.Если вы хотите включить эту функцию в этом браузере, вам следует использовать polyfill (смотрите раздел Callback аргументы).

### Возвращаемое значение

Возвращаемый `intervalID` представляет из себя ненулевое числовое значение, которое идентифицирует таймер, созданный вызовом `setInterval()`; Это значение может быть передано в `clearInterval()` (en-US) для отмены таймера.

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

**Примечание:** The `delay` parameter 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.

Примеры
-------

### Пример 1: Базовый синтаксис

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

```js
var intervalID = window.setInterval(myCallback, 500);

function myCallback() {
  // Your code here
}
```

### Пример 2: Чередование двух цветов

В следующем примере вызывается функция `flashtext()` раз в секунду, до того момента, как будет нажата кнопка Stop.

```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' это тернарный оператор.
 }

 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>
```

### Пример 3: Симуляция пишущей машинки

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).

Аргументы колбэк-функции
------------------------

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/ru/docs/Web/API/window.setInterval
|\*| https://developer.mozilla.org/User:fusionchess
|\*|
|\*| Syntax:
|\*| var timeoutID = window.setTimeout(func, delay[, param1, param2, ...]);
|\*| var timeoutID = window.setTimeout(code, delay);
|\*| var intervalID = window.setInterval(func, delay[, param1, param2, ...]);
|\*| 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.

Проблема с "`this`"
-------------------

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.

### Объяснение

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 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.

Новое тестируемое свойство:

```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 - фреймворк для управления таймерами
-----------------------------------------------

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/ru/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.

### Синтаксис
```

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

### Описание

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

#### Параметры

`thisObject`

The `this` object on which the *callback* function is called. It can be an `object` or `null`.

`callback`

The function that is repeatedly invoked . **It is called with three parameters**: *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` 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`

Промежуток времени (в миллисекундах) между каждым вызовом (чтение / запись).

`myDaemon.length`

Итоговое количество вызовов. Это может быть положительное целое число или бесконечность `Infinity` (чтение / запись).

#### `MiniDaemon` instances methods

`myDaemon.isAtEnd()`

Возвращает логическое значение (true или false), в зависимости от того, находится ли *daemon* в начальной / конечной позиции или нет.

`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).

### Пример использования

Ваша HTML страница:

```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

Примечания
----------

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()`.

### 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`. 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.

### Throttling of intervals

`setInterval()` is subject to the same throttling restrictions in Firefox as `setTimeout()`; see Reasons for delays longer than specified.

Спецификации
------------

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

Совместимость с браузерами
--------------------------

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

Смотрите также
--------------

* Полифил `setInterval`, позволяющий передавать параметры в функцию обратного вызова
* `setTimeout()`
* `clearTimeout()`
* `clearInterval()` (en-US)
* `window.requestAnimationFrame()`


FileList - Интерфейсы веб API

FileList
========

Объект этого типа возвращается свойством `<input>` элемента, что позволяет получить список выбранных файлов из `<input type="file">`. Также используется для получения списка файлов, брошенных в область веб-контента (**Web content**) по средствам drag and drop API. Смотрите DataTransfer (en-US) для детального понимания как это использовать.

**Примечание:** До версии Gecko 1.9.2, input элемент поддерживает только один выбранный файл, это значит что FileList содержит только один файл. Начиная с Gecko 1.9.2, если input содержит атрибут multiple=true, то FileList может содержать несколько файлов.

Использование FileList
----------------------

Все `<input>` элементы имеют файловые массивы которые позволяют получить доступ к файлам. Пример файлового тега:
```

<input id="fileItem" type="file">
```

`Этот код извлекает первый File` object из списка:

```js
var file = document.getElementById("fileItem").files[0];
```

Обзор методов
-------------

| `File item(index);` |
| --- |

Свойства
--------

| Атрибут | Тип | Описание |
| --- | --- | --- |
| `length` | `integer` | Количество файлов в списке, свойство только для чтения (read-only) |

Методы
------

### item()

Возвращает `File` (en-US) объект по его индексу в списке.
```

 File item(
   index
 );
```

###### Параметр

`index`

Отсчитываемый от нуля индекс файла для извлечения из списка.

###### Возвращаемое значение

`Тип File, соотвествует запрашиваемому файлу.`

Примеры
-------

Этот пример выполняет перебор всех файлов, выбранных пользователем, используя элемент Input:

```js
// fileInput это HTML input элемент: <input type="file" id="myfileinput" multiple>
var fileInput = document.getElementById("myfileinput");

// files это FileList объект (похож на NodeList)
var files = fileInput.files;
var file;

// обходит файлы используя цикл
for (var i = 0; i < files.length; i++) {
  // получаем сам файл
  file = files.item(i);
  // или можно так
  file = files[i];

  alert(file.name);
}
```

Здесь пример посложнее.

```html
<!doctype html>
<html>
  <head> </head>
  <body>
    <!--атрибут multiple позволяет выбрать сразу несколько файлов-->

    <input id="myfiles" multiple type="file" />
  </body>

  <script>
 var pullfiles = function () {
 // выбираем файловые инпуты на странице
 var fileInput = document.querySelector("#myfiles");
 var files = fileInput.files;
 // кешируем files.length
 var fl = files.length;
 var i = 0;

 while (i < fl) {
 // локализуем файловую переменную в цикле
 var file = files[i];
 alert(file.name);
 i++;
 }
 };

 // привязываем событие изменения input
 document.querySelector("#myfiles").onchange = pullfiles;

 //a.t
 </script>
</html>
```

Спецификация
------------

* File upload state (HTML5 working draft)
Смотрите также
--------------

* Using files from web applications
* `File` (en-US)
* `FileReader` (en-US)


VRDisplayEvent - Интерфейсы веб API

VRDisplayEvent
==============

**Экспериментальная возможность:** **Это экспериментальная технология**
Так как спецификация этой технологии ещё не стабилизировалась, смотрите таблицу совместимости по поводу использования в различных браузерах. Также заметьте, что синтаксис и поведение экспериментальной технологии может измениться в будущих версиях браузеров, вслед за изменениями спецификации.

Интерфейс VRDisplayEvent API WebVR представляет объект событий, связанных с WebVR (Подробнее - см. Список расширений окна WebVR)

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

`VRDisplayEvent.VRDisplayEvent()` (en-US)

Создаёт экземпляр объекта VRDisplayEvent.

Properties
----------

*`VRDisplayEvent` также наследует свойства от своего родительского объекта, `Event`.*

`VRDisplayEvent.display` Только для чтения

`VRDisplay` (en-US) связанный с этим событием.

`VRDisplayEvent.reason` (en-US) Только для чтения

Определяемая человеческим фактором причина, по которой произошло событие.

Examples
--------

```js
window.addEventListener("vrdisplaypresentchange", function (e) {
  console.log(
    "Display " +
      e.display.displayId +
      " presentation has changed. Reason given: " +
      e.reason +
      ".",
  );
});
```

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

#### No specification found

No specification data found for `api.VRDisplayEvent`.
Check for problems with this page or contribute a missing `spec_url` to mdn/browser-compat-data. Also make sure the specification is included in w3c/browser-specs.

Совместимость с браузерами
--------------------------

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

See also
--------

* WebVR API


DOMStringMap - Интерфейсы веб API

DOMStringMap
============

Used by the `dataset` HTML attribute to represent data for custom attributes added to elements.

Доступные методы
----------------

| `DOMString getDataAttr(in DOMString prop);` |
| --- |
| `boolean hasDataAttr(in DOMString prop);` |
| `void removeDataAttr(in DOMString prop);` |
| `void removeProp(in nsIAtom attr);` |
| `void setDataAttr(in DOMString prop, in DOMString value);` |

Методы
------

### hasDataAttr()
```

boolean hasDataAttr(
  in DOMString prop
);
```

#### Аргументы

`prop`

The property for which to check for the existence of a value.

#### Возвращаемое значение

`true` if the property exists; otherwise `false`.

### removeDataAttr()
```

void removeDataAttr(
  in DOMString prop
);
```

#### Parameters

`prop`

The property to remove from the data set.

### removeProp()

Removes the property from the dataset object. Used to update the dataset object when data-\* attribute has been removed from the element.
```

void removeProp(
  in nsIAtom attr
);
```

#### Parameters

`attr`

The property to remove from the dataset.

Совместимость с браузерами
--------------------------

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

Смотрите также
--------------

* `HTMLElement.dataset` (en-US)
* `dataset`


HTMLMediaElement - Интерфейсы веб API

HTMLMediaElement
================

Интерфейс HTMLMediaElement добавляет к `HTMLElement` свойства и методы, необходимые для поддержки базовых мультимедийных возможностей, общих для аудио и видео. Элементы `HTMLVideoElement` и `HTMLAudioElement` наследуют этот интерфейс.

Свойства
--------

*Этот интерфейс также наследует свойства от своих предков `HTMLElement`, `Element`, `Node` и `EventTarget`.*

`HTMLMediaElement.audioTracks` (en-US)

`AudioTrackList` (en-US), в котором перечислены объекты `AudioTrack` (en-US), содержащиеся в элементе.

`HTMLMediaElement.autoplay` (en-US)

`Boolean`, который отражает атрибут HTML `autoplay`, указывающий, должно ли воспроизведение начинаться автоматически, как только будет доступно достаточно медиафайлов, чтобы сделать это без прерывания.

**Примечание:** Примечание. Сайты, которые автоматически воспроизводят аудио (или видео с аудиодорожкой), могут быть неприятными для пользователей, поэтому их следует по возможности избегать. Если вы должны предлагать функцию автозапуска, вы должны включить её (требуется, чтобы пользователь специально включил её). Однако это может быть полезно при создании элементов мультимедиа, источник которых будет установлен позднее под контролем пользователя.

`HTMLMediaElement.buffered` (en-US) Только для чтения

Возвращает объект `TimeRanges` (en-US), который указывает диапазоны медиаисточника, который браузер буферизировал (если есть) в момент обращения к свойству `buffered`.

`HTMLMediaElement.controller` (en-US)

Объект `MediaController`, представляющий медиа-контроллер, назначенный элементу, либо `null`, если ни один не назначен.

`HTMLMediaElement.controls` (en-US)

Является `Boolean`, который отражает атрибут HTML `controls`, указывающий, должны ли отображаться элементы пользовательского интерфейса для управления ресурсом.

`HTMLMediaElement.controlsList` (en-US) Только для чтения

Возвращает `DOMTokenList`, который помогает агенту пользователя выбирать элементы управления для отображения на элементе мультимедиа всякий раз, когда агент пользователя показывает свой собственный набор элементов управления. DOMTokenList принимает одно или несколько из трёх возможных значений: nodownload, nofullscreen и noremoteplayback.

`HTMLMediaElement.crossOrigin` (en-US)

`DOMString`, указывающий настройку CORS для этого медиаэлемента.

`HTMLMediaElement.currentSrc` (en-US) Только для чтения

Возвращает `DOMString` с абсолютным URL-адресом выбранного медиа-ресурса.

`HTMLMediaElement.currentTime` (en-US)

Двойное значение, обозначающее текущее время воспроизведения в секундах. Установка этого значения ищет носитель в новое время.

`HTMLMediaElement.defaultMuted` (en-US)

Является `Boolean`, который отражает атрибут HTML `muted`, который указывает, должен ли звук вывода медиа-элемента по умолчанию отключаться.

`HTMLMediaElement.defaultPlaybackRate` (en-US)

Двойное значение, обозначающее скорость воспроизведения по умолчанию для мультимедиа.

`HTMLMediaElement.disableRemotePlayback` (en-US)

`Boolean`, который устанавливает или возвращает состояние удалённого воспроизведения, указывая, разрешено ли медиаэлементу иметь удалённый пользовательский интерфейс воспроизведения.

`HTMLMediaElement.duration` Только для чтения

Возвращает значение типа double, указывающее длину носителя в секундах, или 0, если данные носителя отсутствуют.

`HTMLMediaElement.ended` (en-US) Только для чтения

Возвращает `Boolean`, который указывает, закончил ли воспроизведение медиа-элемент.

`HTMLMediaElement.error` (en-US) Только для чтения

Возвращает объект `MediaError` для самой последней ошибки или `null`, если ошибки не было.

`HTMLMediaElement.loop` (en-US)

Является `Boolean`, который отражает атрибут HTML `loop`, который указывает, должен ли медиа-элемент начинаться сначала, когда он достигает конца.

`HTMLMediaElement.mediaGroup` (en-US)

Это `DOMString`, который отражает атрибут HTML `mediagroup`, который указывает имя группы элементов, к которой он принадлежит. Группа медиа-элементов имеет общий `MediaController`.

`HTMLMediaElement.mediaKeys` (en-US) Только для чтения
Экспериментальная возможность

Возвращает объект `MediaKeys` (en-US) или ноль. MediaKeys - это набор ключей, которые связанный HTMLMediaElement может использовать для дешифрования мультимедийных данных во время воспроизведения.

`HTMLMediaElement.mozAudioCaptured` Только для чтения
Non-standard

Возвращает `Boolean`. Связанный с захватом аудиопотока.

`HTMLMediaElement.mozFragmentEnd`
Non-standard

Двойник, обеспечивающий доступ к времени окончания фрагмента, если медиа-элемент имеет URI-фрагмент для currentSrc, в противном случае он равен продолжительности медиа.

`HTMLMediaElement.mozFrameBufferLength`
Non-standard

Устарело

Это unsigned long, который указывает число выборок, которые будут возвращены в кадровом буфере каждого события MozAudioAvailable. Это число является общим для всех каналов, и по умолчанию установлено количество каналов \* 1024 (например, 2 канала \* 1024 выборок = всего 2048).

Для свойства mozFrameBufferLength может быть установлено новое значение для более низкой задержки, больших объёмов данных и т. Д. Указанный размер должен быть числом от 512 до 16384. Использование любого другого размера приводит к возникновению исключения. Лучшее время для установки новой длины - после того, как сработало событие загруженных метаданных, когда известна аудиоинформация, но до того, как аудио началось, или события MozAudioAvailable начали срабатывать.

`HTMLMediaElement.mozSampleRate` Только для чтения
Non-standard

Устарело

Возвращает двойное число, представляющее количество семплов в секунду, которые будут воспроизведены. Например, 44100 выборок в секунду - это частота дискретизации, используемая аудио CD.

`HTMLMediaElement.muted` (en-US)

`Boolean`, определяющий, отключён ли звук. true, если звук отключён, и false в противном случае.

`HTMLMediaElement.networkState` (en-US) Только для чтения

Возвращает unsigned short (перечисление), указывающее текущее состояние выборки мультимедиа по сети.

`HTMLMediaElement.paused` (en-US) Только для чтения

Возвращает `Boolean`, который указывает, приостановлен ли медиа-элемент.

`HTMLMediaElement.playbackRate` (en-US)

Двойное число, указывающее скорость воспроизведения мультимедиа.

`HTMLMediaElement.played` Только для чтения

Возвращает объект `TimeRanges` (en-US), который содержит диапазоны медиаисточников, которые воспроизводил браузер, если таковые имеются.

`HTMLMediaElement.preload`

Это `DOMString`, который отражает атрибут HTML `preload`, указывающий, какие данные должны быть предварительно загружены, если таковые имеются. Возможные значения: `none`, `metadata`, `auto`.

`HTMLMediaElement.preservesPitch` (en-US)
Non-standard

Является `Boolean`, который определяет, будет ли сохранена высота звука. Если установлено значение false, высота звука будет регулироваться в зависимости от скорости звука. Это реализовано с помощью префиксов в Firefox (mozPreservedPitch) и WebKit (webkitPreservedPitch).

`HTMLMediaElement.readyState` (en-US) Только для чтения

Возвращает `unsigned short` (перечисление), указывающее состояние готовности носителя.

`HTMLMediaElement.seekable` (en-US) Только для чтения

Возвращает объект `TimeRanges` (en-US), который содержит временные диапазоны, к которым пользователь может обращаться, если таковые имеются.

`HTMLMediaElement.seeking` Только для чтения

Возвращает `Boolean`, который указывает, находится ли медиа в процессе поиска новой позиции.

`HTMLMediaElement.sinkId` (en-US) Только для чтения
Экспериментальная возможность

Возвращает `DOMString`, который является уникальным идентификатором аудиоустройства, предоставляющего выходные данные, или пустую строку, если используется пользовательский агент по умолчанию. Этот идентификатор должен быть одним из значений MediaDeviceInfo.deviceid, возвращаемых из `MediaDevices.enumerateDevices ()`, id-multimedia или id-communications.

`HTMLMediaElement.src` (en-US)

Это `DOMString`, который отражает атрибут HTML `src`, который содержит URL-адрес используемого медиа-ресурса.

`HTMLMediaElement.srcObject` (en-US)

`MediaStream`, представляющий медиафайл для воспроизведения или воспроизведённый в текущем HTMLMediaElement, или null, если не назначен.

`HTMLMediaElement.textTracks` (en-US) Только для чтения

Возвращает список объектов `TextTrack` (en-US), содержащихся в элементе.

`HTMLMediaElement.videoTracks` (en-US) Только для чтения

Возвращает список объектов `VideoTrack` (en-US), содержащихся в элементе.

**Примечание:** Gecko поддерживает воспроизведение только одной дорожки, а разбор метаданных дорожек доступен только для носителей с форматом контейнера Ogg.

`HTMLMediaElement.volume` (en-US)

Двойной показатель громкости звука, от 0,0 (тихий) до 1,0 (самый громкий).

### Обработчики событий

`HTMLMediaElement.onencrypted` (en-US)

Устанавливает `Event Handler`, вызываемый, когда носитель зашифрован.

`HTMLMediaElement.onwaitingforkey` (en-US)

Устанавливает `EventHandler` (en-US), вызываемый, когда воспроизведение заблокировано во время ожидания ключа шифрования.

Устаревшие атрибуты
-------------------

Эти атрибуты устарели и не должны использоваться, даже если браузер все ещё поддерживает их.

`HTMLMediaElement.initialTime` Только для чтения
Non-standard

Возвращает значение типа double, указывающее начальную позицию воспроизведения в секундах.

`HTMLMediaElement.mozChannels` Только для чтения
Non-standard

Устарело

Возвращает значение типа double, представляющее количество каналов в аудиоресурсе (например, 2 для стерео).

### Устаревшие обработчики событий

`HTMLMediaElement.onmozinterruptbegin`
Non-standard

Устанавливает `EventHandler` (en-US), вызываемый, когда медиа-элемент прерывается из-за менеджера аудио-каналов. Это было специфично для Firefox, оно было реализовано для Firefox OS и было удалено в Firefox 55.

`HTMLMediaElement.onmozinterruptend`
Non-standard

Устанавливает `Event Handler`, вызываемый при завершении прерывания. Это было специфично для Firefox, оно было реализовано для Firefox OS и было удалено в Firefox 55.

Методы
------

*Этот интерфейс также наследует методы от своих предков `HTMLElement`, `Element`, `Node` и `EventTarget`.*

`HTMLMediaElement.addTextTrack()`

Добавляет текстовую дорожку (например, дорожку для субтитров) к элементу мультимедиа.

`HTMLMediaElement.captureStream()` (en-US)
Экспериментальная возможность

Возвращает `MediaStream`, захватывает поток медиа-контента.

`HTMLMediaElement.canPlayType()` (en-US)

Определяет, может ли указанный тип носителя воспроизводиться.

`HTMLMediaElement.fastSeek()` (en-US)

Прямо стремится к данному времени.

`HTMLMediaElement.load()` (en-US)

Сбрасывает носитель в начало и выбирает наилучший из доступных источников из источников, предоставленных с использованием атрибута `src` или элемента `<source>`.

`HTMLMediaElement.mozCaptureStream()`
Non-standard

[введите описание]

`HTMLMediaElement.mozCaptureStreamUntilEnded()`
Non-standard

[введите описание]

`HTMLMediaElement.mozGetMetadata()`
Non-standard

Возвращает `Object`, который содержит свойства, которые представляют метаданные из воспроизводимого медиаресурса в виде пар {key: value}. Отдельная копия данных возвращается каждый раз, когда вызывается метод. Этот метод должен вызываться после возникновения события загруженных метаданных.

`HTMLMediaElement.pause()` (en-US)

Пауза воспроизведения мультимедиа.

`HTMLMediaElement.play()` (en-US)

Начинается воспроизведение мультимедиа.

`HTMLMediaElement.seekToNextFrame()` (en-US)
Non-standard

Экспериментальная возможность

Стремится к следующему кадру в медиа. Этот нестандартный экспериментальный метод позволяет вручную управлять считыванием и воспроизведением мультимедиа с настраиваемой скоростью или перемещаться по мультимедиа покадрово для выполнения фильтрации или других операций.

`HTMLMediaElement.setMediaKeys()` (en-US)
Экспериментальная возможность

Возвращает `Промис`. Устанавливает клавиши `MediaKeys` (en-US), используемые при дешифровании медиафайлов во время воспроизведения.

`HTMLMediaElement.setSinkId()` (en-US)
Экспериментальная возможность

Устанавливает идентификатор аудиоустройства, которое будет использоваться для вывода, и возвращает `Promise`. Это работает только тогда, когда приложение имеет право использовать указанное устройство.

Устаревшие методы
-----------------

Эти методы устарели и не должны использоваться, даже если браузер все ещё поддерживает их.

`HTMLMediaElement.mozLoadFrom()`
Non-standard

Устарело

Этот метод, доступный только в реализации Mozilla, загружает данные из другого медиа-элемента. Это работает аналогично load () за исключением того, что вместо обычного алгоритма выбора ресурса для источника просто устанавливается значение currentSrc другого элемента. Это оптимизировано, так что этот элемент получает доступ ко всем кешированным и буферизованным данным другого элемента; фактически эти два элемента совместно используют загруженные данные, поэтому данные, загруженные любым из этих элементов, доступны обоим.

События
-------

*Наследует методы от своего родителя `HTMLElement`, определённого в миксине `GlobalEventHandlers`. Обработайте эти события, используя addEventListener () или назначив обработчик событий свойству oneventname этого интерфейса.*

`abort`

Срабатывает, когда ресурс загружен не полностью, но не в результате ошибки.

`canplay` (en-US)

Запускается, когда пользовательский агент может воспроизводить мультимедиа, но оценивает, что загружено недостаточно данных для воспроизведения мультимедиа до его конца без необходимости остановки для дальнейшей буферизации контента.

`canplaythrough` (en-US)

Запускается, когда пользовательский агент может воспроизводить мультимедиа, и оценивает, что было загружено достаточно данных для воспроизведения мультимедиа до его конца, без необходимости остановки для дальнейшей буферизации контента.

`durationchange` (en-US)

Запускается, когда атрибут продолжительности был обновлён.

`emptied` (en-US)

Запускается, когда носитель становится пустым; например, когда носитель уже загружен (или частично загружен), и для его перезагрузки вызывается метод `HTMLMediaElement.load ()`.

`ended` (en-US)

Срабатывает, когда воспроизведение останавливается, когда достигнут конец носителя (<audio> или <video>) или если дальнейшие данные недоступны.

`error` (en-US)

Срабатывает, когда ресурс не может быть загружен из-за ошибки.

`loadeddata` (en-US)

Запускается, когда первый кадр носителя завершил загрузку.

`loadedmetadata` (en-US)

Запускается, когда метаданные были загружены

`loadstart` (en-US)

Запускается, когда браузер начал загружать ресурс.

`pause` (en-US)

Вызывается, когда обрабатывается запрос на приостановку воспроизведения, и действие переходит в состояние паузы, чаще всего это происходит, когда вызывается медиа `HTMLMediaElement.pause ()`.

`play` (en-US)

Срабатывает, когда свойство paused изменяется с true на false, в результате использования метода `HTMLMediaElement.play ()` или атрибута autoplay

`playing` (en-US)

Запускается, когда воспроизведение готово начать после приостановки или задержки из-за отсутствия данных.

`progress` (en-US)

Периодически запускается, когда браузер загружает ресурс.

`ratechange` (en-US)

Запускается, когда скорость воспроизведения изменилась.

`seeked`  (en-US)

Запускается, когда скорость воспроизведения изменилась.

`seeking`

Запускается, когда начинается операция поиска

`stalled` (en-US)

Запускается, когда пользовательский агент пытается извлечь данные мультимедиа, но данные неожиданно не поступают.

`suspend` (en-US)

Запускается, когда загрузка медиа-данных была приостановлена.

`timeupdate` (en-US)

Запускается, когда время, указанное атрибутом currentTime, было обновлено.

`volumechange` (en-US)

Запускается при изменении громкости.

`waiting` (en-US)

Срабатывает, когда воспроизведение остановлено из-за временной нехватки данных

Спецификации
------------

| Specification |
| --- |
| HTML Standard # htmlmediaelement |

Совместимость с браузерами
--------------------------

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

Смотрите также
--------------

* Рекомендации
    + `<video>` и `<audio>` HTML-элементы.
    + `HTMLVideoElement` и `HTMLAudioElement` интерфейсы, полученные из HTMLMediaElement.
* Статьи
    + Использование HTML5 аудио и видео (en-US)
    + Медиа форматы, поддерживаемые аудио и видео элементами (en-US)
    + API веб-аудио (en-US)


EventSource - Интерфейсы веб API

EventSource
===========

`Интерфейс EventSource` используется для получения серверных событий (Server-sent events). Он устанавливает соединение с сервером по HTTP и получает события в формате text/event-stream без закрытия соединения.

Вы можете присвоить атрибуту `onmessage` JavaScript-функцию для получения нетипизированных сообщений (то есть сообщений без поля `event`). Вы так же можете вызвать функцию `addEventListener()` для обработки событий так же, как для любого другого источника событий.

См. Using server-sent events для более детальной информации

Свойства
--------

| Attribute | Type | Description |
| --- | --- | --- |
| `onerror` | `nsIDOMEventListener` | JavaScript-функция, вызываемая при появлении ошибки |
| `onmessage` | `nsIDOMEventListener` | JavaScript-функция, вызываемая при приходе сообщения без поля `event` |
| `onopen` | `nsIDOMEventListener` | JavaScript-функция, вызываемая после открытия соединения |
| `readyState` | `long` | Состояние соединения, должно иметь одно из значений `CONNECTING`, `OPEN`, или `CLOSED`. **Только для чтения** |
| `url` | `DOMString` | **Только для чтения** |

В дополнение к открытым атрибутам два внутренних атрибута, которые не открыты напрямую:

reconnection time

Это время в миллисекундах, используемое для определения продолжительности ожидания после неудачной попытки соединения до повторного соединения

last event ID string

По умолчанию пустая строка. Сервер может отправлять сообщение с полем `id` для установки этого значения.

Константы
---------

| Constant | Value | Description |
| --- | --- | --- |
| `CONNECTING` | `0` | Соединение устанавливается |
| `OPEN` | `1` | Соединение открыто, получение событий |
| `CLOSED` | `2` | Соединение не устанавливается, закрыто, или произошла фатальная ошибка |

Методы
------

### close()

Закрывает соединение, если оно существует и устанавливает атрибут `readyState` в значение `CLOSED`. Если соединение уже закрыто, этот метод ничего не делает.
```

void close();
```

###### Параметры

Нет

Спецификации
------------

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

Совместимость с браузерами
--------------------------

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


VRDisplayCapabilities - Интерфейсы веб API

VRDisplayCapabilities
=====================

**Экспериментальная возможность:** **Это экспериментальная технология**
Так как спецификация этой технологии ещё не стабилизировалась, смотрите таблицу совместимости по поводу использования в различных браузерах. Также заметьте, что синтаксис и поведение экспериментальной технологии может измениться в будущих версиях браузеров, вслед за изменениями спецификации.

Интерфейс **VRDisplayCapabilities** WebVR API описывает возможности `VRDisplay` (en-US) - его функции можно использовать для тестирования возможностей устройства Виртуальной Реальности (VR), например, он может возвращать информацию о местоположении.

Данный интерфейс доступен в свойстве `VRDisplay.capabilities` (en-US).

Свойства
--------

`VRDisplayCapabilities.canPresent` (en-US) Только для чтения

Возвращает параметр `Boolean` (en-US), указывающий, способен ли дисплей VR представлять контент (например, через HMD - Наголовный дисплей).

`VRDisplayCapabilities.hasExternalDisplay` (en-US) Только для чтения

Возвращает параметр `Boolean` (en-US), указывающий, является ли дисплей VR отдельным от основного дисплея устройства.

`VRDisplayCapabilities.hasOrientation` (en-US)
Устарело
 Только для чтения

Возвращает параметр `Boolean` (en-US), указывающий, может ли дисплей VR отслеживать и возвращать информацию об ориентации в пространстве .

`VRDisplayCapabilities.hasPosition` Только для чтения

Возвращает параметр `Boolean` (en-US), указывающий, может ли дисплей VR отслеживать и возвращать информацию о положении.

`VRDisplayCapabilities.maxLayers` (en-US) Только для чтения

Возвращает число, указывающее максимальное значение `VRLayer` (en-US), которое дисплей VR может представить одновременно (например, максимальную длину массива, который `VRDisplay.requestPresent ()` может принять.)

Примеры
-------

```js
function reportDisplays() {
  navigator.getVRDisplays().then(function (displays) {
    for (var i = 0; i < displays.length; i++) {
      var cap = displays[i].capabilities;
      // cap is a VRDisplayCapabilities object
      var listItem = document.createElement("li");
      listItem.innerHTML =
        "<strong>Display " +
        (i + 1) +
        "</strong>" +
        "<br>VR Display ID: " +
        displays[i].displayId +
        "<br>VR Display Name: " +
        displays[i].displayName +
        "<br>Display can present content: " +
        cap.canPresent +
        "<br>Display is separate from the computer's main display: " +
        cap.hasExternalDisplay +
        "<br>Display can return position info: " +
        cap.hasPosition +
        "<br>Display can return orientation info: " +
        cap.hasOrientation +
        "<br>Display max layers: " +
        cap.maxLayers;
      list.appendChild(listItem);
    }
  });
}
```

Спецификации
------------

#### No specification found

No specification data found for `api.VRDisplayCapabilities`.
Check for problems with this page or contribute a missing `spec_url` to mdn/browser-compat-data. Also make sure the specification is included in w3c/browser-specs.

Совместимость с браузерами
--------------------------

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

Смотрите также
--------------

* WebVR API