From 074785cea106179cb3305637055ab0a009ca74f2 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:42:52 -0500 Subject: initial commit --- files/ru/dom/document.createelement/index.html | 82 ++ files/ru/dom/document.images/index.html | 29 + files/ru/dom/dom_reference/events/index.html | 80 ++ files/ru/dom/dom_reference/examples/index.html | 382 +++++++++ files/ru/dom/dom_reference/index.html | 387 +++++++++ .../index.html | 50 ++ .../index.html" | 230 ++++++ files/ru/dom/index.html | 61 ++ files/ru/dom/using_fullscreen_mode/index.html | 198 +++++ files/ru/dom/using_web_workers/index.html | 871 +++++++++++++++++++++ .../ru/dom/window.requestanimationframe/index.html | 92 +++ 11 files changed, 2462 insertions(+) create mode 100644 files/ru/dom/document.createelement/index.html create mode 100644 files/ru/dom/document.images/index.html create mode 100644 files/ru/dom/dom_reference/events/index.html create mode 100644 files/ru/dom/dom_reference/examples/index.html create mode 100644 files/ru/dom/dom_reference/index.html create mode 100644 files/ru/dom/dom_reference/locating_dom_elements_using_selectors/index.html create mode 100644 "files/ru/dom/dom_reference/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265/index.html" create mode 100644 files/ru/dom/index.html create mode 100644 files/ru/dom/using_fullscreen_mode/index.html create mode 100644 files/ru/dom/using_web_workers/index.html create mode 100644 files/ru/dom/window.requestanimationframe/index.html (limited to 'files/ru/dom') diff --git a/files/ru/dom/document.createelement/index.html b/files/ru/dom/document.createelement/index.html new file mode 100644 index 0000000000..15542d751d --- /dev/null +++ b/files/ru/dom/document.createelement/index.html @@ -0,0 +1,82 @@ +--- +title: document.createElement +slug: DOM/document.createElement +tags: + - DOM + - Gecko +translation_of: Web/API/Document/createElement +--- +

{{ ApiRef() }}

+ +

Общая информация

+ +

В HTML-документах создает элемент c тем тегом, что указан в аргументе или HTMLUnknownElement, если имя тега не распознаётся.

+ +

В XUL-документах создает указанный в аргументе элемент XUL.

+ +

В остальных случаях создаёт элемент с нулевым NamespaceURI.

+ +

Параметры

+ +
var element = document.createElement(tagName, [options]);
+
+ + + +

Пример

+ +

Данный пример создает новый элемент <div> и вставляет его перед элементом с идентификатором org_div1:

+ +
<!DOCTYPE html>
+<html>
+<head>
+<title>||Работа с элементами||</title>
+</head>
+
+<body>
+<div><h1>Привет!</h1></div>
+<div id='org_div1'>Текст выше сгенерирован автоматически.</div>
+</body>
+
+<script>
+  document.body.onload = addElement;
+  var my_div = newDiv = null;
+
+  function addElement() {
+
+    // Создаем новый элемент div
+    // и добавляем в него немного контента
+
+    var newDiv = document.createElement("div");
+        newDiv.innerHTML = "<h1>Привет!</h1>";
+
+    // Добавляем только что созданый элемент в дерево DOM
+
+    my_div = document.getElementById("org_div1");
+    document.body.insertBefore(newDiv, my_div);
+  }
+</script>
+</html>
+
+ +

Заметки

+ +

Если существуют атрибуты со значениями по умолчанию, атрибуты узлов предоставляющие их создаются автоматически и применяются к элементу.

+ +

Для создания элементов с заданым пространством имен используйте метод createElementNS.

+ +

Реализация createElement в Gecko не соответствует DOM спецификации для XUL и XHTML документов: localName и namespaceURI не устанавливаются в  null в созданном документе. Смотрите {{ Bug(280692) }} для подробностей.

+ +

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

+ +

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

+ +

DOM 2 Модуль: createElement

+ +

{{ languages( { "fr": "fr/DOM/document.createElement", "it": "it/DOM/document.createElement", "pl": "pl/DOM/document.createElement" } ) }}

diff --git a/files/ru/dom/document.images/index.html b/files/ru/dom/document.images/index.html new file mode 100644 index 0000000000..c9ba4ac1e2 --- /dev/null +++ b/files/ru/dom/document.images/index.html @@ -0,0 +1,29 @@ +--- +title: document.images +slug: DOM/document.images +tags: + - DOM + - JavaScript +translation_of: Web/API/Document/images +--- +

{{ ApiRef() }}

+

Кратко об обьекте

+

document.images возвращает коллекцию изображений в текущем HTML документе.

+

Синтаксис

+
var htmlCollection = document.images;
+
+

Пример

+
var images = document.images;
+
+for(var i = 0; i < images.length; i++) {
+    if(images[i].src == "banner.gif") {
+      alert('Баннер найден!');
+    };
+};
+
+

Примечания

+

document.images.length — возвращает количество изображений на странице.

+

document.images является частью DOM HTML, и работает только в HTML документах.

+

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

+

DOM Level 2 HTML: HTMLDocument.images

+

{{ languages( { "en": "en/DOM/document.images", "fr": "fr/DOM/document.images", "pl": "pl/DOM/document.images","ru":"ru/DOM/document.images" } ) }}

diff --git a/files/ru/dom/dom_reference/events/index.html b/files/ru/dom/dom_reference/events/index.html new file mode 100644 index 0000000000..eeadb57328 --- /dev/null +++ b/files/ru/dom/dom_reference/events/index.html @@ -0,0 +1,80 @@ +--- +title: Events and the DOM +slug: DOM/DOM_Reference/Events +translation_of: Web/API/Document_Object_Model/Events +--- +

Вступление

+ +

Вступление

+ +

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

+ +

Существует отличная диаграмма, которая четко объясняет события трех этапов через DOM в проекте DOM Level 3 Events .

+ +

Также см. Пример 5: Распространение событий в главе «Примеры» для более подробного примера.

+ +

Регистрация слушателей событий

+ +

Есть 3 способа регистрации обработанных событий для элемента DOM.

+ +

EventTarget.addEventListener

+ +
// Предполагая, что myButton является элементом кнопки
+myButton.addEventListener ('click', greet, false);
+function greet (event) {
+    // распечатать и посмотреть на объект события
+    // всегда печатать аргументы в случае пропуска любых других аргументов
+    console.log ('greet:', arguments);
+    оповещение («Привет, мир»);
+}
+
+ +

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

+ +

Примечание. Internet Explorer 6-8 не поддерживает этот метод, предлагая аналогичный {{domxref ("EventTarget.attachEvent")}} API. Для кросс-браузерной совместимости используйте одну из множества доступных библиотек JavaScript.

+ +

Дополнительную информацию можно найти на справочной странице {{domxref ("EventTarget.addEventListener")}}.

+ +

Атрибут HTML

+ +
<button onclick = "alert ('Hello world!')">
+
+ +

Код JavaScript в атрибуте передается объекту Event через eventпараметр. Возвращаемое значение обрабатывается особым образом, описанным в спецификации HTML .

+ +

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

+ +

Свойства элемента DOM

+ +
// Предполагая, что myButton является элементом кнопки
+myButton.onclick = function(event){alert('Hello world');};
+
+ +

Функция может быть определена для получения eventпараметра. Возвращаемое значение обрабатывается особым образом, описанным в спецификации HTML .

+ +

Проблема этого метода в том, что для каждого элемента и для каждого события может быть установлен только один обработчик.

+ +

Доступ к интерфейсам событий

+ +

Обработчики событий могут быть присоединены к различным объектам, включая элементы DOM, документ, объект окна и т. Д. Когда происходит событие, объект события создается и последовательно передается слушателям события.

+ +

Интерфейс {{domxref ("Event")}} доступен из функции-обработчика через объект события, переданный в качестве первого аргумента. В следующем простом примере показано, как объект события передается в функцию-обработчик события и может использоваться из одной такой функции.

+ +
function print(evt) {
+  // параметру evt автоматически назначается объект события
+  // позаботимся о различиях в console.log и alert
+  console.log('print:', evt);
+  alert(evt);
+}
+// любая функция должна иметь подходящее имя, это то, что называется семантическим
+table_el.onclick = print; 
+
+ + + + diff --git a/files/ru/dom/dom_reference/examples/index.html b/files/ru/dom/dom_reference/examples/index.html new file mode 100644 index 0000000000..a3332f7585 --- /dev/null +++ b/files/ru/dom/dom_reference/examples/index.html @@ -0,0 +1,382 @@ +--- +title: Examples of web and XML development using the DOM +slug: DOM/DOM_Reference/Examples +translation_of: Web/API/Document_Object_Model/Examples +--- +

В этой главе представлены более длинные примеры разработки веб-сайтов и XML с использованием DOM. По возможности, примеры используют общие API, трюки и шаблоны в JavaScript для управления объектом документа.

+ +

Пример 1: высота и ширина

+ +

В следующем примере показано использование свойств высоты и ширины для изображений разных размеров:
+  

+ +
<!DOCTYPE html>
+<html lang="en">
+<head>
+<title>width/height example</title>
+<script>
+function init() {
+  var arrImages = new Array(3);
+
+  arrImages[0] = document.getElementById("image1");
+  arrImages[1] = document.getElementById("image2");
+  arrImages[2] = document.getElementById("image3");
+
+  var objOutput = document.getElementById("output");
+  var strHtml = "<ul>";
+
+  for (var i = 0; i < arrImages.length; i++) {
+    strHtml += "<li>image" + (i+1) +
+            ": height=" + arrImages[i].height +
+            ", width=" + arrImages[i].width +
+            ", style.height=" + arrImages[i].style.height +
+            ", style.width=" + arrImages[i].style.width +
+            "<\/li>";
+  }
+
+  strHtml += "<\/ul>";
+
+  objOutput.innerHTML = strHtml;
+}
+</script>
+</head>
+<body onload="init();">
+
+<p>Image 1: no height, width, or style
+  <img id="image1" src="http://www.mozilla.org/images/mozilla-banner.gif">
+</p>
+
+<p>Image 2: height="50", width="500", but no style
+  <img id="image2"
+       src="http://www.mozilla.org/images/mozilla-banner.gif"
+       height="50" width="500">
+</p>
+
+<p>Image 3: no height, width, but style="height: 50px; width: 500px;"
+  <img id="image3"
+       src="http://www.mozilla.org/images/mozilla-banner.gif"
+       style="height: 50px; width: 500px;">
+</p>
+
+<div id="output"> </div>
+</body>
+</html>
+
+ +

Пример 2: Аттрибуты Изображения

+ +
<!DOCTYPE html>
+<html lang="en">
+<head>
+<title>Modifying an image border</title>
+
+<script>
+function setBorderWidth(width) {
+  document.getElementById("img1").style.borderWidth = width + "px";
+}
+</script>
+</head>
+
+<body>
+<p>
+  <img id="img1"
+       src="image1.gif"
+       style="border: 5px solid green;"
+       width="100" height="100" alt="border test">
+</p>
+
+<form name="FormName">
+  <input type="button" value="Make border 20px-wide" onclick="setBorderWidth(20);" />
+  <input type="button" value="Make border 5px-wide"  onclick="setBorderWidth(5);" />
+</form>
+
+</body>
+</html>
+
+ +

Пример 3: Управление Стилями

+ +

В этом простом примере, некоторые базовые свойства стиля элемента абзаца HTML доступны с помощью объекта стиля элемента и свойств стиля CSS этого объекта, который можно получить и установить из DOM. В этом случае вы напрямую управляете отдельными стилями. В следующем примере (см. Пример 4), вы можете использовать таблицы стилей и их правила для изменения стилей для целых документов.

+ +
<!DOCTYPE html>
+<html lang="en">
+<head>
+<title>Changing color and font-size example</title>
+
+<script>
+function changeText() {
+  var p = document.getElementById("pid");
+
+  p.style.color = "blue"
+  p.style.fontSize = "18pt"
+}
+</script>
+</head>
+<body>
+
+<p id="pid" onclick="window.location.href = 'http://www.cnn.com/';">linker</p>
+
+<form>
+  <p><input value="rec" type="button" onclick="changeText();" /></p>
+</form>
+
+</body>
+</html>
+
+ +

Пример 4: Использование Стилей

+ +

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

+ +
var ss = document.styleSheets;
+
+for(var i = 0; i < ss.length; i++) {
+  for(var j = 0; j < ss[i].cssRules.length; j++) {
+    dump( ss[i].cssRules[j].selectorText + "\n" );
+  }
+}
+ +

Для документа с единой таблицей стилей, в которой определены следующие три правила:

+ +
body { background-color: darkblue; }
+p { font-face: Arial; font-size: 10pt; margin-left: .125in; }
+#lumpy { display: none; }
+
+ +

Этот скрипт выводит следующее:

+ +
BODY
+P
+#LUMPY
+
+ +

Пример 5: Распространение Событий

+ +

Этот пример демонстрирует, как события срабатывают и обрабатываются в DOM очень простым путём. Когда загружается BODY в составе HTML-документа, обработчик событий регистрируется в верхней строке таблицы TABLE. Обработчик событий реагирует на событие запуском функции stopEvent, изменяющей значение в нижней ячейке.

+ +

Однако, stopEvent также вызывает метод объекта событий, {{domxref("event.stopPropagation")}}, что препятствует дальнейшему всплытию события в DOM. Обратите внимание, что сама таблица имеет {{domxref("element.onclick","onclick")}} обработчик событий, который должен отображать сообщение при нажатии на таблицу. Но метод stopEvent метод прекратил распространение, и поэтому после обновления данных в таблице фаза события эффективно завершается, и отображается окно предупреждения для подтверждения.

+ +
<!DOCTYPE html>
+<html lang="en">
+<head>
+<title>Event Propagation</title>
+
+<style>
+#t-daddy { border: 1px solid red }
+#c1 { background-color: pink; }
+</style>
+
+<script>
+function stopEvent(ev) {
+  c2 = document.getElementById("c2");
+  c2.innerHTML = "hello";
+
+  // this ought to keep t-daddy from getting the click.
+  ev.stopPropagation();
+  alert("event propagation halted.");
+}
+
+function load() {
+  elem = document.getElementById("tbl1");
+  elem.addEventListener("click", stopEvent, false);
+}
+</script>
+</head>
+
+<body onload="load();">
+
+<table id="t-daddy" onclick="alert('hi');">
+  <tr id="tbl1">
+    <td id="c1">one</td>
+  </tr>
+  <tr>
+    <td id="c2">two</td>
+  </tr>
+</table>
+
+</body>
+</html>
+
+ +

Пример 6: getComputedStyle

+ +

Этот пример показывает как {{domxref("window.getComputedStyle")}} метод может использоваться для получения стилей элемента, которые не заданы с помощью атрибута style или с помощью JavaScript (e.g., elt.style.backgroundColor="rgb(173, 216, 230)"). Эти последние типы стилей можно получить с помощью более прямых {{domxref("element.style", "elt.style")}} свойств, которые указаны в DOM CSS Properties List.

+ +

getComputedStyle () возвращает объект ComputedCSSStyleDeclaration, свойства индивидуального стиля которого могут ссылаться на метод getPropertyValue () этого объекта, как показано в следующем примере документа.

+ +
<!DOCTYPE html>
+<html lang="en">
+<head>
+
+<title>getComputedStyle example</title>
+
+<script>
+function cStyles() {
+  var RefDiv = document.getElementById("d1");
+  var txtHeight = document.getElementById("t1");
+  var h_style = document.defaultView.getComputedStyle(RefDiv, null).getPropertyValue("height");
+
+  txtHeight.value = h_style;
+
+  var txtWidth = document.getElementById("t2");
+  var w_style = document.defaultView.getComputedStyle(RefDiv, null).getPropertyValue("width");
+
+  txtWidth.value = w_style;
+
+  var txtBackgroundColor = document.getElementById("t3");
+  var b_style = document.defaultView.getComputedStyle(RefDiv, null).getPropertyValue("background-color");
+
+  txtBackgroundColor.value = b_style;
+}
+</script>
+
+<style>
+#d1 {
+  margin-left: 10px;
+  background-color: rgb(173, 216, 230);
+  height: 20px;
+  max-width: 20px;
+}
+</style>
+
+</head>
+
+<body>
+
+<div id="d1">&nbsp;</div>
+
+<form action="">
+  <p>
+    <button type="button" onclick="cStyles();">getComputedStyle</button>
+    height<input id="t1" type="text" value="1" />
+    max-width<input id="t2" type="text" value="2" />
+    bg-color<input id="t3" type="text" value="3" />
+  </p>
+</form>
+
+</body>
+</html>
+
+ +

Пример 7: Отображение Свойств Событий Объекта

+ + + +

В этом примере используются методы DOM для отображения всех свойств объекта {{domxref ("window.onload")}} {{domxref ("event")}} и их значений в таблице. Он также показывает полезный метод использования цикла for..in для итерации по свойствам объекта для получения их значений.

+ +

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

+ +

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

+ + + +
<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8"/>
+<title>Show Event properties</title>
+
+<style>
+table { border-collapse: collapse; }
+thead { font-weight: bold; }
+td { padding: 2px 10px 2px 10px; }
+
+.odd { background-color: #efdfef; }
+.even { background-color: #ffffff; }
+</style>
+
+<script>
+
+function showEventProperties(e) {
+  function addCell(row, text) {
+    var cell = row.insertCell(-1);
+    cell.appendChild(document.createTextNode(text));
+  }
+
+  var e = e || window.event;
+  document.getElementById('eventType').innerHTML = e.type;
+
+  var table = document.createElement('table');
+  var thead = table.createTHead();
+  var row = thead.insertRow(-1);
+  var lableList = ['#', 'Property', 'Value'];
+  var len = lableList.length;
+
+  for (var i=0; i<len; i++) {
+    addCell(row, lableList[i]);
+  }
+
+  var tbody = document.createElement('tbody');
+  table.appendChild(tbody);
+
+  for (var p in e) {
+    row = tbody.insertRow(-1);
+    row.className = (row.rowIndex % 2)? 'odd':'even';
+    addCell(row, row.rowIndex);
+    addCell(row, p);
+    addCell(row, e[p]);
+  }
+
+  document.body.appendChild(table);
+}
+
+window.onload = function(event){
+  showEventProperties(event);
+}
+</script>
+</head>
+
+<body>
+<h1>Properties of the DOM <span id="eventType"></span> Event Object</h1>
+</body>
+
+</html>
+
+ +

Пример 8: Использование интерфейса таблицы DOM

+ + + +

Интерфейс DOM HTMLTableElement предоставляет некоторые удобные методы для создания и управления таблицами. Два часто используемых метода: {{domxref ("HTMLTableElement.insertRow")}} и {{domxref ("tableRow.insertCell")}}.

+ +

Чтобы добавить строку и некоторые ячейки в существующую таблицу:

+ + + +
<table id="table0">
+ <tr>
+  <td>Row 0 Cell 0</td>
+  <td>Row 0 Cell 1</td>
+ </tr>
+</table>
+
+<script>
+var table = document.getElementById('table0');
+var row = table.insertRow(-1);
+var cell,
+    text;
+
+for (var i = 0; i < 2; i++) {
+  cell = row.insertCell(-1);
+  text = 'Row ' + row.rowIndex + ' Cell ' + i;
+  cell.appendChild(document.createTextNode(text));
+}
+</script>
+
+ +

Заметки

+ + + + + + diff --git a/files/ru/dom/dom_reference/index.html b/files/ru/dom/dom_reference/index.html new file mode 100644 index 0000000000..db06b01dd8 --- /dev/null +++ b/files/ru/dom/dom_reference/index.html @@ -0,0 +1,387 @@ +--- +title: Руководство по DOM +slug: DOM/DOM_Reference +tags: + - DOM + - DOM Reference + - DOM интерфейс + - Intermediate + - Руководство +translation_of: Web/API/Document_Object_Model +--- +

Объектная Модель Документа (DOM) является программным интерфейсом для HTML, XML и SVG документов. Это обеспечивает структурированное представление документа (дерева), и определяет способ, по которому структура может быть доступна для программы, для изменения структуры документа, его стиля и содержания. DOM обеспечивает представление документа в виде структурированной группы узлов и объектов, которые имеют свойства и методы. По сути, она связывает веб -страницы со скриптами или языками программирования.

+ +

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

+ +

Введение в DOM доступно.

+ +

DOM интерфейсы

+ +
+ +
+ +

Устаревшие интерфейсы

+ +

Объектная модель документа находится в процессе значительного упрощения. Для того, чтобы достигнуть этого следующие интерфейсы, присутствующие на различных DOM level 3 или более ранних спецификациях были удалены. До сих пор неясно, будут ли некоторые из них возвращены, но на данный момент они должны быть рассмотрены как устаревшие, и их использования следует избегать:

+ +
+ +
+ +

HTML интерфейсы

+ +

Документ, содержащий HTML описывается с помощью {{domxref("HTMLDocument")}} интерфейса. Обратите внимание, что HTML спецификация также расширяет {{domxref("Document")}} интерфейс.

+ +

Объект HTMLDocument также даёт доступ к следующим возможностям браузера: вкладки, окна, в которых отрисовывается страница, используя интерфейс {{domxref("Window")}}, асcоциированный с ним {{domxref("window.style", "Style")}} (обычно CSS), история браузера, относящаяся к контексту, {{domxref("window.history", "History")}}, в конце концов, {{domxref("Selection")}} в документе.

+ +

Интерфейсы HTML элементов

+ +
+ +
+ +

Другие интерфейсы

+ +
+ +
+ +

Устаревшие HTML интерфейсы

+ +
+ +
+ +

SVG интерфейсы

+ +

Интерфейсы SVG элементов

+ +
+ +
+ +

Интерфейсы SVG данных

+ +

DOM API для типов данных, используемых в определениях SVG свойств и атрибутов.

+ +
+

Замечание: Начиная с {{Gecko("5.0")}}, следующие относящиеся к SVG DOM интерфейсы, представляя списки объектов, индексируются и к ним можно иметь доступ как к массивам; к тому же, у них есть свойство длины, обозначающее количество элементов в списках: {{domxref("SVGLengthList")}}, {{domxref("SVGNumberList")}}, {{domxref("SVGPathSegList")}} и {{domxref("SVGPointList")}}.

+
+ +

Статический тип

+ +
+ +
+ +

Анимированный тип

+ +
+ +
+ +

Относящиеся к SMIL

+ +
+ +
+ +

Другие SVG интерфейсы

+ +
+ +
+ +

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

+ + + +
+
+
diff --git a/files/ru/dom/dom_reference/locating_dom_elements_using_selectors/index.html b/files/ru/dom/dom_reference/locating_dom_elements_using_selectors/index.html new file mode 100644 index 0000000000..73538e8616 --- /dev/null +++ b/files/ru/dom/dom_reference/locating_dom_elements_using_selectors/index.html @@ -0,0 +1,50 @@ +--- +title: Locating DOM elements using selectors +slug: DOM/DOM_Reference/Locating_DOM_elements_using_selectors +translation_of: Web/API/Document_object_model/Locating_DOM_elements_using_selectors +--- +
{{ gecko_minversion_header("1.9.1") }}
+ +
Selectors API предоставляет методы, с помощью которых можно быстро и просто получить доступ к узлам Element из DOM путем сопоставления с набором селекторов. Это намного быстрее, чем прошлые техники, где надо было, например, использовать цикл в JS-коде, чтобы найти конкретные элементы.
+ +
 
+ +

Интерфейс NodeSelector (The NodeSelector interface)

+ +

Эта спецификация добавляет два новых метода к любым объектам, реализующим интерфейс Document, DocumentFragment, или Element:

+ +
+
querySelector
+
Возвращает первый совпадающий узел Element внутри поддерева. Если совпадающих узлов нет, будет возвращен null.
+
querySelectorAll
+
Возвращает NodeList, содержащий все подходящие узлы Element внутри поддерева узлов. Или возвращает пустой NodeList, если совпадений не найдено.
+
+ +
Замечание: NodeList, возвращаемый методом querySelectorAll(), не настоящий. Этот список отличается от других методов поиска DOM, которые возвращают настоящие (живые) узлы.
+ +

Вы можете найти примеры и детали, прочитав документацию для методов querySelector() и querySelectorAll(), а также в статье Code snippets for querySelector.

+ +

Selectors

+ +

Селекторные методы принимают один или больше селекторов, разделенных запятыми, чтобы определить, какие элементы должны быть возвращены. Например, чтобы все параграфы в документе, которые имеют классы warning или note, можно сделать следующее:

+ +
var special = document.querySelectorAll( "p.warning, p.note" );
+ +

Также можно искать по ID. Например:

+ +
var el = document.querySelector( "#main, #basic, #exclamation" );
+ +

После выполнения кода выше, el будет содержать первый элемент в документе, чей ID main, basic или exclamation

+ +

Вы можете использовать любые CSS-селекторы в методах querySelector(), querySelectorAll()

+ +

See also

+ + diff --git "a/files/ru/dom/dom_reference/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265/index.html" "b/files/ru/dom/dom_reference/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265/index.html" new file mode 100644 index 0000000000..3c02e5799f --- /dev/null +++ "b/files/ru/dom/dom_reference/\320\262\320\262\320\265\320\264\320\265\320\275\320\270\320\265/index.html" @@ -0,0 +1,230 @@ +--- +title: Введение +slug: DOM/DOM_Reference/Введение +tags: + - DOM +translation_of: Web/API/Document_Object_Model/Introduction +--- +
+

Этот раздел представляет краткое знакомство с Объектной Моделью Документа (DOM) - что такое DOM, каким образом предоставляются структуры HTML и XML документов, и как взаимодействовать с ними. Данный раздел содержит справочную информацию и примеры.

+ +

Что такое Объектная Модель Документа (DOM)?

+ +

Объектная Модель Документа (DOM) – это программный интерфейс (API) для HTML и XML документов. DOM предоставляет структурированное представление документа и определяет то, как эта структура может быть доступна из программ, которые могут изменять содержимое, стиль и структуру документа. Представление DOM состоит из структурированной группы узлов и объектов, которые имеют свойства и методы. По существу, DOM соединяет веб-страницу с языками описания сценариев либо языками программирования.
+
+ Веб-страница – это документ. Документ может быть представлен как в окне браузера, так и в самом HTML-коде. В любом случае, это один и тот же документ. DOM предоставляет другой способ представления, хранения и управления этого документа. DOM полностью поддерживает объектно-ориентированнное представление веб-страницы, делая возможным её изменение при помощи языка описания сценариев наподобие JavaScript.
+
+ Стандарты W3C DOM и WHATWG DOM формируют основы DOM, реализованные в большинстве современных браузеров. Многие браузеры предлагают расширения за пределами данного стандарта, поэтому необходимо проверять работоспособность тех или иных возможностей DOM для каждого конкретного браузера.

+ +

Например: стандарт DOM описывает, что метод getElementsByTagName в коде, указанном ниже, должен возращать список всех элементов <p> в документе.

+ +
paragraphs = document.getElementsByTagName("P");
+// paragraphs[0] это первый <p> элемент
+// paragraphs[1] это второй <p> элемент и т.д.
+alert(paragraphs[0].nodeName);
+ +

Все свойства, методы и события, доступные для управления и создания новых страниц, организованы в виде объектов. Например, объект document, который представляет сам документ, объект table, который реализует специальный интерфейс DOM HTMLTableElement, необходимый для доступа к HTML-таблицам, и так далее. Данная документация даёт справку об объектах DOM, реализованных Gecko-подобных браузерах.

+ +

DOM и JavaScript

+ +

Небольшой пример выше, как почти все примеры в этой справке – это JavaScript. То есть пример написан на JavaScript, но при этом используется DOM для доступа к документу и его элементам. DOM не является языком программирования, но без него JavaScript не имел бы никакой модели или представления о веб-странице, HTML-документе, XML-документе и их элементах. Каждый элемент в документе - весь документ в целом, заголовок, таблицы внутри документа, заголовки таблицы, текст внутри ячеек таблицы - это части объектной документной модели для этого документа, поэтому все они могут быть доступны и могут изменяться с помощью DOM и скриптового языка наподобие JavaScript.

+ +

Вначале JavaScript и DOM были тесно связаны, но впоследствии они развились в различные сущности. Содержимое страницы хранится в DOM и может быть доступно и изменяться с использованием JavaScript, поэтому мы можем записать это в виде приблизительного равенства:

+ +

API (веб либо XML страница) = DOM + JS (язык описания скриптов)

+ +

DOM спроектирован таким образом, чтобы быть независимым от любого конкретного языка программирования, обеспечивая структурное представление документа согласно единому и последовательному API. Хотя мы всецело сфокусированы на JavaScript в этой справочной документации, реализация DOM может быть построена для любого языка, как в следующем примере на Python:

+
+ +
# Пример DOM на языке Python
+import xml.dom.minidom as m
+doc = m.parse("C:\\Projects\\Py\\chap1.xml");
+doc.nodeName # Свойство объекта документа DOM;
+p_list = doc.getElementsByTagName("para");
+ +

Для подробной информации о том, какие технологии участвуют в написании JavaScript для веб, смотрите обзорную статью JavaScript technologies overview.

+ +

Каким образом доступен DOM? 

+ +

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

+ +

При создании сценария с использованием элемента <script>, либо включая в веб страницу инструкцию для загрузки скрипта, вы можете немедленно приступить к использованию программного интерфейса (API), используя элементы document или window для взаимодействия с самим документом, либо для получения потомков этого документа, т.е. различных элементов на странице. Ваше программирование DOM может быть чем-то простым, например, вывод сообщения с использованием функции alert() объекта window, или использовать более сложные методы DOM, которые создают новое содержимое, как показанно в следующем примере:

+ +
<body onload="window.alert('добро пожаловать на мою домашнюю страницу!');">
+
+ +

В следующем примере внутри элемента <script> определен код JavaScript, данный код устанавливает функцию при загрузке документа (когда весь DOM доступен для использования). Эта функция создает новый элемент H1, добавляет текст в данный элемент, а затем добавляет H1 в дерево документа:

+ +
<html>
+  <head>
+    <script>
+    // запуск данной функции при загрузке документа
+       window.onload = function() {
+    // создание нескольких элементов
+    // в пустой HTML странице
+       heading = document.createElement("h1");
+       heading_text = document.createTextNode("Big Head!");
+       heading.appendChild(heading_text);
+       document.body.appendChild(heading);
+      }
+    </script>
+  </head>
+  <body>
+  </body>
+</html>
+ +

Важные типы данных

+ +

Данный раздел предназначен для краткого описания различных типов и объектов в простой и доступной манере. Существует некоторое количество различных типов данных, которые используются в API, на которые вы должны обратить внимание. Для простоты, синтаксис примеров в данном разделе обычно ссылается на узлы как на elements, на массивы узлов как на nodeLists ( либо просто elements ) и на атрибуты узла, просто как на attributes.

+ +

Ниже таблица с кратким описанием этих типов данных.

+ + + + + + + + + + + + + + + + + + + + + + + + +
documentКогда член возвращает объект типа document (например, свойство элемента ownerDocument возвращает документ к которому он относится), этот обьект document является собственным корневым обьектом. В DOM document Reference разделе описан объект document.
+ element   
elementобозначает элемент или узел типа element, возвращаемый членом DOM API. Вместо того, чтобы говорить, что метод document.createElement() возвращает ссылку на node, мы просто скажем, что этот элемент возвращает element, который просто был создан в DOM. Объекты element реализуют DOM element интерфейс и также более общий Node интерфейс. Оба интерфейса включены в эту справку.
+ nodeList
NodeList +

массив элементов, как тот, что возвращается методом Document.getElementsByTagName(). Конкретные элементы в массиве доступны по индексу двумя способами:

+ +
    +
  •     list.item(1)
  • +
  •     list[1]
  • +
+ +

Эти способы эквивалентны. В первом способе item() - единственный метод объекта NodeList. Последний использует обычный синтаксис массивов, чтобы получить второе значение в списке.

+
attributeКогда attribute возвращается членом API (например, метод createAttribute()) - это будет ссылка на объект, который предоставляет специальный (хоть и небольшой) интерфейс для атрибутов. Атрибуты - это узлы в DOM, как и элементы, хотя вы можете редко использовать их в таком виде.
namedNodeMapnamedNodeMap подобна массиву, но элементы доступны по имени или индексу. Доступ по индексу - это лишь для удобства перечисления, т.к. элементы не имеют определенног порядка в списке. Этот тип данных имеет метод item() для этих целей и вы можете также добавлять и удалять элементы из namedNodeMap
+ + + +

DOM-интерфейсы (DOM interfaces)

+ + + +

Это руководство об объектах и реальных вещах, которые вы можете использовать для управления DOM-иерархией. Есть много моментов, где понимание того, как это работает, может удивлять. Например, объект, представляющий HTML form элемент, берет своё свойство name из интерфейса HTMLFormElement, а свойство className - из интерфейса HTMLElement. В обоих случаях свойство, которое вы хотите, находится в этом объекте формы.

+ +

Кроме того, отношение между объектами и интерфейсами, которые они реализуют в DOM может быть удивительным и этот раздел пытается рассказать немного о существующих интерфейсах в DOM и о том, как они могут быть доступны.

+ +

Интерфейсы и объекты (Interfaces and objects)

+ +

Многие объекты реализуют действия из нескольких интерфейсов. Объект таблицы, например, реализует специальный HTML Table Element Interface, который включает такие методы как createCaption и insertRow. Но так как это таблица - это ещё и HTML-элемент, table реализует интерфейс Element, описанный в разделе DOM element Reference. Наконец, так как HTML-элемент (в смысле DOM) - это узел (node) в дереве, которое составляет объектную модель для HTML- или XML-страницы, табличный элемент также реализует более общий интерфейс Node, из которого происходит Element.

+ +

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

+ +
var table = document.getElementById("table");
+var tableAttrs = table.attributes; // Node/Element interface
+for (var i = 0; i < tableAttrs.length; i++) {
+  // HTMLTableElement interface: border attribute
+  if(tableAttrs[i].nodeName.toLowerCase() == "border")
+    table.border = "1";
+}
+// HTMLTableElement interface: summary attribute
+table.summary = "note: increased border";
+ +

Основные интерфейсы в DOM (Core interfaces in the DOM)

+ +

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

+ +

Document, window - это объекты, чьи интерфейсы вы, как правило, очень часто используете в программировании DOM. Говоря простыми словами, объект window представляет что-то вроде браузера, а объект document - корень самого документа. Element наследуется от общего интерфейса Node, и эти интерфейсы вместе предоставляют много методов и свойств, которые можно применять у отдельных элементов. Эти элементы также могут иметь отдельные интерфейсы для работы с типами данных, которые эти элементы содержат, как в примере с объектом table в предыдущем случае.

+ +

Ниже представлен краткий список распространненых членов API, используемых в программировании веб- и XML-страниц с использованием DOM:

+ + + +

Тестирование DOM API

+ +

Этот документ содержит примеры для каждого интерфейса, который вы можете использовать в своей разработке. В некоторых случаях примеры - полноценные веб-страницы с доступом к DOM в элементе <script>, также перечислены элементы, необходимые чтобы запустить скрипт в форме, и HTML-элементы, над которыми будут производиться операции DOM. Когда встречается такой случай, можно просто копировать и вставить пример в новый HTML-документ, сохранить и запустить его в браузере.

+ +

Есть случаи, однако, где примеры более лаконичные. Чтобы запустить примеры, которые лишь демонстрируют основы взаимодействия интерфейсов с HTML-элементами, вы можете подготовить тестовую страницу, в которую будете помещать функции внутрь скриптов. Следующая очень простая веб-страница содержит элемент <script> в заголовке, в который вы можете поместить функции, чтобы протестировать интерфейс. Страница содержит несколько элементов с атрибутами, которые можно возвращать, устанавливать или, другими словами, манипулировать и содержит пользовательский интерфейс, необходимый, чтобы вызывать нужные функции из браузера.

+ +

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

+ +
<html>
+  <head>
+    <title>DOM Tests</title>
+    <script type="application/javascript">
+    function setBodyAttr(attr, value){
+      if (document.body) eval('document.body.'+attr+'="'+value+'"');
+      else notSupported();
+    }
+    </script>
+  </head>
+  <body>
+    <div style="margin: .5in; height: 400;">
+      <p><b><tt>text</tt></b></p>
+      <form>
+        <select onChange="setBodyAttr('text',
+        this.options[this.selectedIndex].value);">
+          <option value="black">black
+          <option value="darkblue">darkblue
+        </select>
+        <p><b><tt>bgColor</tt></b></p>
+        <select onChange="setBodyAttr('bgColor',
+        this.options[this.selectedIndex].value);">
+          <option value="white">white
+          <option value="lightgrey">gray
+        </select>
+        <p><b><tt>link</tt></b></p>
+        <select onChange="setBodyAttr('link',
+        this.options[this.selectedIndex].value);">
+          <option value="blue">blue
+          <option value="green">green
+        </select>  <small>
+        <a href="http://www.brownhen.com/dom_api_top.html" id="sample">
+        (sample link)</a></small><br>
+      </form>
+      <form>
+        <input type="button" value="version" onclick="ver()" />
+      </form>
+    </div>
+  </body>
+</html>
+ +

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

+ +

+ +

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

+ +

Другие статьи

+ + diff --git a/files/ru/dom/index.html b/files/ru/dom/index.html new file mode 100644 index 0000000000..eb6f785d55 --- /dev/null +++ b/files/ru/dom/index.html @@ -0,0 +1,61 @@ +--- +title: DOM +slug: DOM +tags: + - DOM +translation_of: Web/API/Document_Object_Model +--- +
+

Объектная модель документа (DOM) — это API для HTML и XML документов. Она предоставляет структуру документа, что позволяет изменять его содержимое и внешний вид. По сути, она связывает веб-страницы со скриптами или языками программирования.

+
+ + + + + + + +
+

Документация

+
+
+ Справочная информация по Gecko DOM
+
+ Объектная модель документа движка Gecko.
+
+ Об объектной модели документа
+
+ Краткое введение в DOM.
+
+ Динамически изменяемый пользовательский интерфейс на XUL
+
+ Основы управления XUL UI с помощью методов DOM.
+
+ DOM и JavaScript
+
+ Что такое DOM? Что такое JavaScript? Как мне использовать их совместно на моей веб-странице? Этот документ отвечает на эти и другие вопросы.
+
+ Объектная модель документа Mozilla
+
+ Более старая документация по DOM, размещенная на mozilla.org.
+
+

Посмотреть все...

+
+

Сообщество

+
    +
  • Форумы Mozilla... {{ DiscussionList("dev-tech-dom", "mozilla.dev.tech.dom") }}
  • +
+

Инструменты

+ +

Посмотреть все...

+ + +
+

 

diff --git a/files/ru/dom/using_fullscreen_mode/index.html b/files/ru/dom/using_fullscreen_mode/index.html new file mode 100644 index 0000000000..ad21d6d20e --- /dev/null +++ b/files/ru/dom/using_fullscreen_mode/index.html @@ -0,0 +1,198 @@ +--- +title: Fullscreen API +slug: DOM/Using_fullscreen_mode +translation_of: Web/API/Fullscreen_API +--- +
{{DefaultAPISidebar("Fullscreen API")}}
+ +

The Fullscreen API adds methods to present a specific {{DOMxRef("Element")}} (and its descendants) in full-screen mode, and to exit full-screen mode once it is no longer needed. This makes it possible to present desired content—such as an online game—using the user's entire screen, removing all browser user interface elements and other applications from the screen until full-screen mode is shut off.

+ +

See the article Guide to the Fullscreen API for details on how to use the API.

+ +
+

Note: Support for this API varies somewhat across browsers, with many requiring vendor prefixes and/or not implementing the latest specification. See the {{anch("Browser compatibility")}} section below for details on support for this API. You may wish to consider using a library such as Fscreen for vendor agnostic access to the Fullscreen API.

+
+ +

Interfaces

+ +

The Fullscreen API has no interfaces of its own. Instead, it augments several other interfaces to add the methods, properties, and event handlers needed to provide full-screen functionality. These are listed in the following sections.

+ +

Methods

+ +

The Fullscreen API adds methods to the {{DOMxRef("Document")}} and {{DOMxRef("Element")}} interfaces to allow turning off and on full-screen mode.

+ +

Methods on the Document interface

+ +
+
{{DOMxRef("Document.exitFullscreen()")}}
+
Requests that the {{Glossary("user agent")}} switch from full-screen mode back to windowed mode. Returns a {{jsxref("Promise")}} which is resolved once full-screen mode has been completely shut off.
+
+ +

Methods on the Element interface

+ +
+
{{DOMxRef("Element.requestFullscreen()")}}
+
Asks the user agent to place the specified element (and, by extension, its descendants) into full-screen mode, removing all of the browser's UI elements as well as all other applications from the screen. Returns a {{jsxref("Promise")}} which is resolved once full-screen mode has been activated.
+
+ +

Properties

+ +

The {{DOMxRef("Document")}} interface provides properties that can be used to determine if full-screen mode is supported and available, and if full-screen mode is currently active, which element is using the screen.

+ +
+
{{DOMxRef("DocumentOrShadowRoot.fullscreenElement")}}
+
The fullscreenElement property tells you the {{DOMxRef("Element")}} that's currently being displayed in full-screen mode on the DOM (or shadow DOM). If this is null, the document is not in full-screen mode.
+
{{DOMxRef("Document.fullscreenEnabled")}}
+
The fullscreenEnabled property tells you whether or not it is possible to engage full-screen mode. This is false if full-screen mode is not available for any reason (such as the "fullscreen" feature not being allowed, or full-screen mode not being supported).
+
+ +

Event handlers

+ +

The Fullscreen API defines two events which can be used to detect when full-screen mode is turned on and off, as well as when errors occur during the process of changing between full-screen and windowed modes. Event handlers for these events are available on the {{DOMxRef("Document")}} and {{DOMxRef("Element")}} interfaces.

+ +
+

Note: These event handler properties are not available as HTML content attributes. In other words, you cannot specify event handlers for {{Event("fullscreenchange")}} and {{Event("fullscreenerror")}} in the HTML content. They must be added by JavaScript code.

+
+ +

Event handlers on documents

+ +
+
{{DOMxRef("Document.onfullscreenchange")}}
+
An event handler for the {{Event("fullscreenchange")}} event that's sent to a {{DOMxRef("Document")}} when that document is placed into full-screen mode, or when that document exits full-screen mode. This handler is called only when the entire document is presented in full-screen mode.
+
{{DOMxRef("Document.onfullscreenerror")}}
+
An event handler for the {{Event("fullscreenerror")}} event that gets sent to a {{DOMxRef("Document")}} when an error occurs while trying to enable or disable full-screen mode for the entire document.
+
+ +

Event handlers on elements

+ +
+
{{DOMxRef("Element.onfullscreenchange")}}
+
An event handler which is called when the {{Event("fullscreenchange")}} event is sent to the element, indicating that the element has been placed into, or removed from, full-screen mode.
+
{{DOMxRef("Element.onfullscreenerror")}}
+
An event handler for the {{Event("fullscreenerror")}} event when sent to an element which has encountered an error while transitioning into or out of full-screen mode.
+
+ +

Obsolete properties

+ +
+
{{DOMxRef("Document.fullscreen")}} {{Deprecated_Inline}}
+
A Boolean value which is true if the document has an element currently being displayed in full-screen mode; otherwise, this returns false. +
Note: Use the {{DOMxRef("Document.fullscreenElement", "fullscreenElement")}} property on the {{DOMxRef("Document")}} or {{DOMxRef("ShadowRoot")}} instead; if it's not null, then it's an {{DOMxRef("Element")}} currently being displayed in full-screen mode.
+
+
+ +

Events

+ +

The Fullscreen API defines two events which can be used to detect when full-screen mode is turned on and off, as well as when errors occur during the process of changing between full-screen and windowed modes.

+ +
+
{{Event("fullscreenchange")}}
+
Sent to a {{DOMxRef("Document")}} or {{DOMxRef("Element")}} when it transitions into or out of full-screen mode.
+
{{Event("fullscreenerror")}}
+
Sent to a Document or Element if an error occurs while attempting to switch it into or out of full-screen mode.
+
+ +

Dictionaries

+ +
+
{{DOMxRef("FullscreenOptions")}}
+
Provides optional settings you can specify when calling {{DOMxRef("Element.requestFullscreen", "requestFullscreen()")}}.
+
+ +

Controlling access

+ +

The availability of full-screen mode can be controlled using Feature Policy. The full-screen mode feature is identified by the string "fullscreen", with a default allow-list value of "self", meaning that full-screen mode is permitted in top-level document contexts, as well as to nested browsing contexts loaded from the same origin as the top-most document.

+ +

See Using Feature Policy to learn more about using Feature Policy to control access to an API.

+ +

Usage notes

+ +

Users can choose to exit full-screen mode simply by pressing the ESC (or F11) key, rather than waiting for the site or app to programmatically do so. Make sure you provide, somewhere in your user interface, appropriate user interface elements that inform the user that this option is available to them.

+ +
+

Note: Navigating to another page, changing tabs, or switching to another application using any application switcher (or Alt-Tab) will likewise exit full-screen mode.

+
+ +

Example

+ +

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

+ +

View Live Examples

+ +

Watching for the Enter key

+ +

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

+ +
document.addEventListener("keypress", function(e) {
+  if (e.keyCode === 13) {
+    toggleFullScreen();
+  }
+}, false);
+
+ +

Toggling full-screen mode

+ +

This code is called by the event handler above when the user hits the Enter key.

+ +
function toggleFullScreen() {
+  if (!document.fullscreenElement) {
+      document.documentElement.requestFullscreen();
+  } else {
+    if (document.exitFullscreen) {
+      document.exitFullscreen();
+    }
+  }
+}
+ +

This starts by looking at the value of the {{DOMxRef("Document", "document")}}'s fullscreenElement attribute. In a real-world deployment, at this time, you'll want to check for prefixed versions of this (mozFullScreenElement, msFullscreenElement, or webkitFullscreenElement, for example). If the value is null, the document is currently in windowed mode, so we need to switch to full-screen mode; otherwise, it's the element that's currently in full-screen mode. Switching to full-screen mode is done by calling {{DOMxRef("Element.requestFullscreen()")}} on the {{HTMLElement("video")}} element.

+ +

If full-screen mode is already active (fullscreenElement is not null), we call {{DOMxRef("Document.exitFullscreen", "exitFullscreen()")}} on the document to shut off full-screen mode.

+ +

Specifications

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName("Fullscreen")}}{{Spec2("Fullscreen")}}Initial version.
+ +

Browser compatibility

+ +

Document.fullscreen

+ +
+ + +

{{Compat("api.Document.fullscreen")}}

+
+ +

Document.fullscreenEnabled

+ +
+ + +

{{Compat("api.Document.fullscreenEnabled")}}

+
+ +

See also

+ + diff --git a/files/ru/dom/using_web_workers/index.html b/files/ru/dom/using_web_workers/index.html new file mode 100644 index 0000000000..7503eccacb --- /dev/null +++ b/files/ru/dom/using_web_workers/index.html @@ -0,0 +1,871 @@ +--- +title: Использование Web Workers +slug: DOM/Using_web_workers +tags: + - воркер + - поток +translation_of: Web/API/Web_Workers_API/Using_web_workers +--- +
{{DefaultAPISidebar("Web Workers API")}}
+ +

Web Worker-ы предоставляют простое средство для запуска скриптов в фоновом потоке. Поток Worker'а может выполнять задачи без вмешательства в пользовательский интерфейс. К тому же, они могут осуществлять ввод/вывод, используя XMLHttpRequest (хотя атрибуты responseXML и channel всегда будут равны null). Существующий Worker может отсылать сообщения JavaScript коду-создателю через обработчик событий, указанный этим кодом (и наоборот). Эта статья дает детальную инструкцию по использованию Web Workers.

+ +

Web Workers API

+ +

Worker - это объект, создаваемый конструктором (например, {{domxref("Worker.Worker", "Worker()")}}) и запускающий именной JavaScript файл — этот файл содержит код, который будет выполнен в потоке Worker'а; объекты же Workers запускаются в другом глобальном контексте, отличающемся от текущего, - {{domxref("window")}}. Поэтому использование переменной {{domxref("window")}} для получения текущего глобального контекста (вместо {{domxref("window.self","self")}}) внутри {{domxref("Worker")}} вернет ошибку.

+ +

Контекст Worker'а представлен объектом {{domxref("DedicatedWorkerGlobalScope")}} в случае выделенных Workers (обычные Workers используются одним скриптом; совместные Workers используют объект {{domxref("SharedWorkerGlobalScope")}}). Выделенный Worker доступен только из скрипта-родителя, в то время как совместные Workers могут быть доступны из нескольких сценариев.

+ +
+

Заметка: Смотрите страницу Web Workers API для справки по Workers и прочие руководства.

+
+ +

Вы можете запускать любой код внутри потока worker-а, за некоторыми исключениями. Например, вы не можете прямо манипулировать DOM внутри worker-а, или использовать некоторые методы по умолчанию и свойства объекта {{domxref("window")}}. Но вы можете использовать большой набор опций, доступный под Window, включая WebSockets, и механизмы хранения данных, таких как IndexedDB и относящихся только к Firefox OS Data Store API. Для дополнительной информации смотрите Functions and classes available to workers.

+ +

Данные передаются между worker-ами и главным потоком через систему сообщений — обе стороны передают свои сообщения, используя метод postMessage() и отвечают на сообщения при помощи обработчика событий onmessage (сообщение хранится в аттрибуте data события {{event("Message")}}). Данные при этом копируются, а не делятся.

+ +

Объекты Workers могут, в свою очередь, создавать новые объекты workers, и так до тех пор, пока всё работает в рамках текущей страницы. Плюс к этому, объекты workers могут использовать XMLHttpRequest для сетевого ввода/вывода, но есть исключение - атрибуты responseXML и channel объекта XMLHttpRequest всегда возвращают null.

+ +

Выделенные Workers

+ +

Как уже упоминалось выше, выделенный Worker доступен только для скрипта, который его вызвал. В этом разделе речь пойдет о JavaScript, который можно найти в нашем основном примере выделенного Worker (запустить скрипт): этот пример позволяет ввести два числа для умножения. Эти числа отправляются в Worker, перемножаются, а результат возвращается на страницу и отображается.

+ +

Этот пример достаточно тривиален, но для ознакомления с базовыми концепциями worker-ов мы решили его упростить. Более продвинутые детали описаны далее в статье.

+ +

Определение поддержки Worker

+ +

Для большего контроля над ошибками и обратной совместимости, рекомендуется обернуть ваш код доступа к worker-у в следующий (main.js):

+ +
if (window.Worker) {
+
+  ...
+
+}
+ +

Создание выделенного worker

+ +

Создание нового worker-а — это легко. Всё что вам нужно это вызвать конструктор {{domxref("Worker.Worker", "Worker()")}}, указав URI скрипта для выполнения в потоке worker-а (main.js):

+ +
+
var myWorker = new Worker("worker.js");
+
+
+ +

Передача сообщений в и из выделенного worker

+ +

Магия worker-ов происходит через {{domxref("Worker.postMessage", "postMessage()")}} метод и обработчик событий {{domxref("Worker.onmessage", "onmessage")}}. Когда вы хотите отправить сообщение в worker, вы доставляете сообщение к нему вот так (main.js):

+ +
first.onchange = function() {
+  myWorker.postMessage([first.value,second.value]);
+  console.log('Message posted to worker');
+}
+
+second.onchange = function() {
+  myWorker.postMessage([first.value,second.value]);
+  console.log('Message posted to worker');
+}
+ +

В приведенном фрагменте кода мы имеем два {{htmlelement("input")}} элемента, представленных переменными first и second; когда значение любой из переменных изменяется, myWorker.postMessage([first.value,second.value]) используется для отправки обоих значений, представленных в виде массива, в worker. Посредством аргумента message возможна передача практически любых данных в worker.

+ +

Внутри worker-a мы можем обрабатывать сообщения и отвечать на них при помощи добавления обработчика события onmessage подобным образом (worker.js):

+ +
onmessage = function(e) {
+  console.log('Message received from main script');
+  var workerResult = 'Result: ' + (e.data[0] * e.data[1]);
+  console.log('Posting message back to main script');
+  postMessage(workerResult);
+}
+ +

Обработчик onmessage позволяет нам запустить некий код всякий раз, когда получен пакет с сообщением, доступным в атрибуте data события message. В примере выше мы просто перемножаем вместе две цифры, после чего используем postMessage() снова, чтобы отправить полученный результат назад в основной поток.

+ +

Возвращаясь в основной поток, мы используем onmessage снова, чтобы отреагировать на сообщение, отправленное нам назад из worker-а:

+ +
myWorker.onmessage = function(e) {
+  result.textContent = e.data;
+  console.log('Message received from worker');
+}
+ +

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

+ +

Заметка: Обратите внимание, что onmessage()​ и postmessage() должны вызываться из экземпляра Worker в главном потоке, но не в потоке worker-а. Это связано с тем, что внутри потока worker-а, worker выступает в качестве глобального объекта.

+ +

Заметка: При передаче сообщения между основным потоком и потоком worker-а, оно копируется или "передается" (перемещается), не делится между потоками. Читайте {{anch("Transferring data to and from workers: further details")}} для более подробного объяснения.

+ +

Завершение работы worker-а

+ +

Прекращение работы worker-а главного потока достигается методом {{domxref("Worker", "terminate")}}:

+ +
myWorker.terminate();
+ +

Поток worker-а немедленно уничтожается.

+ +

Обработка ошибок

+ +

При ошибке во время выполнения worker-а, вызывается его обработчик событий onerror. Он принимает событие error, которое реализует интерфейс ErrorEvent.

+ +

Событие не всплывает и его можно отменить. Для отмены действия по умолчанию, worker может вызвать метод preventDefault() в обработчике события ошибки.

+ +

У события ошибки есть три поля, которые представляют интерес:

+ +
+
message
+
Сообщение об ошибке в читаемом виде.
+
filename
+
Имя файла со скриптом, в котором ошибка произошла.
+
lineno
+
Номер строки в файле, в котором произошла ошибка.
+
+ +

Создание subworkers

+ +

Worker-ы могут запускать другие worker-ы. Так называемые sub-worker'ы должны быть того же происхождения (same-origin), что и родительский документ. Кроме того, URI для subworker-ов рассчитываются относительно родительского worker'а, а не родительского документа. Это позволяет worker-ам проще следить за тем, где находятся их зависимости.

+ +

Импорт скриптов и библиотек

+ +

Worker потоки имеют доступ к глобальной функции, importScripts(), которая позволяет импортировать скрипты с того же домена в их область видимости. Функция принимает ноль и более URI параметров, как список ссылок на ресурсы для импорта; все нижеприведенные примеры верны:

+ +
importScripts();                        /* imports nothing */
+importScripts('foo.js');                /* imports just "foo.js" */
+importScripts('foo.js', 'bar.js');      /* imports two scripts */
+
+ +

Браузер загружает каждый указанный скрипт и исполняет его. Любые глобальные объекты, создаваемые каждым скриптом могут быть использованы в worker'е. Если скрипт не удалось загрузить, будет брошена ошибка NETWORK_ERROR, и последующий код не будет исполнен. Тем не менее код, исполненный ранее (включая отложенный при помощи {{domxref("window.setTimeout()")}}) останется функционален. Объявления функций идущие после вызова метода importScripts() также будут доступны, т.к. объявления функций всегда обрабатываются перед остальным кодом.

+ +
Заметка: Скрипты могут быть загружены в произвольном порядке, но их исполнение будет в  том порядке, в котором имена файлов были переданы в importScripts(). Функция выполняется синхронно; importScripts() не вернет исполнение, пока все скрипты не будут загружены и исполнены.
+ +

Разделяемые worker-ы (Shared workers)

+ +

Разделяемый worker доступен нескольким разным скриптам — даже если они находятся в разных окнах, фреймах или даже worker-ах. В этом разделе мы обсудим JavaScript, который можно найти в нашем базовом примере разделяемых worker-ов (запустить разделяемый worker): Он очень похож на базовый пример выделенных worker-ов, за исключением двух функций, которые доступны из разных скриптовых файлов: умножение двух чисел или возведение числа в степень. Оба скрипта используют один и тот же worker для необходимых вычислений.

+ +

Здесь мы сосредоточимся на разнице между выделенными и раздялемыми worker-ами. Обратите внимание, что в данном примере есть две HTML страницы с JavaScript кодом, которые используют один и тот же файл worker-а.

+ +
+

Заметка: Если разделяемый worker может быть доступен из нескольких контекстов просмотра, то все они должны иметь одно и то же происхождение (одни и те же протокол, хост и порт).

+
+ +
+

Заметка: В Firefox разделяемый worker не может быть использован совместно документами в приватном и неприватном окне ({{bug(1177621)}}).

+
+ +

Создание разделяемого worker-а

+ +

Запуск разделяемого worker-а очень похож на запуск выделенного worker-а, но используется другой конструктор (см. index.html и index2.html) — в каждом документе необходимо поднять worker, для этого следует написать такой код:

+ +
var myWorker = new SharedWorker("worker.js");
+ +

Большая разница заключается в том, что с разделяемым worker-ом необходимо взаимодействовать через объект port — явно открыв порт, с помощью которого скрипты могут взаимодействовать с worker-ом (в случае выделенного worker-а это происходит неявно).

+ +

Соединение с портом должно быть осуществлено либо неявно, используя обработчик событие onmessage, либо явно, вызвав метод start() перед тем, как отправлять любые сообщения. Вызов метода start() необходим только тогда, когда подписка на событие реализована через метод addEventListener().

+ +
+

Заметка: Когда используется метод start() чтобы открыть соединение с портом, его необходимо вызывать и в родительском потоке и в потоке worker-а, если необходима двухсторонняя коммуникация.

+
+ +
myWorker.port.start();  // в родительском потоке
+ +
port.start();  // в потоке worker-а, где переменная port является ссылкой на порт
+ +

Передача сообщений в/из разделяемого worker-а

+ +

Теперь сообщения могут быть отправлены worker-у, как и прежде, но метод postMessage() должен вызываться из объекта port (еще раз, вы можете увидеть схожие кострукции в multiply.js и square.js):

+ +
squareNumber.onchange = function() {
+  myWorker.port.postMessage([squareNumber.value,squareNumber.value]);
+  console.log('Message posted to worker');
+}
+ +

Теперь на стороне worker-а. Здесь код немного сложнее (worker.js):

+ +
self.addEventListener('connect', function(e) { // требуется addEventListener()
+  var port = e.ports[0];
+  port.onmessage = function(e) {
+    var workerResult = 'Result: ' + (e.data[0] * e.data[1]);
+    port.postMessage(workerResult);
+  }
+  port.start();  // вызов необязательный, т.к. используется обработчик событий onmessage
+});
+ +

Первый этап состоит из события onconnect. Оно срабатывает, когда произошло подключение (т.е. когда в родительском потоке отработало событие onmessage или когда в нем был вызван метод start()).

+ +

Мы используем атрибут события ports, чтобы получить порт и сохранить его в переменной.

+ +

Второй этап — это обработчик события message на сохраненном порту. Он нужен для подсчета и вывода результата вычисления в основной поток. Установка обработчика message в потоке worker-а также открывает подключение к родительскому потоку, поэтому вызов на port.start() на самом деле не нужен (см. код обработчика onconnect).

+ +

Последний этап — возвращение в основной поток и обработка сообщения от worker‑а (еще раз, вы можете увидеть схожие конструкции в multiply.js и square.js):

+ +
myWorker.port.onmessage = function(e) {
+  result2.textContent = e.data[0];
+  console.log('Message received from worker');
+}
+ +

Когда сообщение приходит через порт от worker-а, мы проверяем тип результата вычислений и затем вставляем его в соответствующий абзац.

+ +

О потоковой безопасности

+ +

Интерфейс {{domxref("Worker")}} создаёт настоящие потоки на уровне операционной системы, что может смутить опытных программистов и навести их на мысли о проблемах, связанных с конфликтом доступа к общим объектам.

+ +

На самом деле создать такие проблемы достаточно сложно, так как worker-ы жёстко контролируются. У них нет доступа к непотокобезопасным объектам DOM, а все данные между потоками передаются в качестве сериализованных объектов. Придётся очень постараться, чтобы вызывать проблемы потокобезопасности в вашем коде.

+ +

Передача данных в и из worker-ов: другие детали

+ +

Передача данных между главной страницей и worker-ом происходит путем копирования, а не передачи по ссылке. Объекты сериализуются при передаче и затем десериализуются на другом конце. Страница и worker не используют совместно одни и те же экземпляры, для каждого создается свой. Большинство браузеров реализуют это структурированным клонированием (structured cloning).

+ +

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

+ +
function emulateMessage (vVal) {
+    return eval("(" + JSON.stringify(vVal) + ")");
+}
+
+// Tests
+
+// test #1
+var example1 = new Number(3);
+console.log(typeof example1); // object
+console.log(typeof emulateMessage(example1)); // number
+
+// test #2
+var example2 = true;
+console.log(typeof example2); // boolean
+console.log(typeof emulateMessage(example2)); // boolean
+
+// test #3
+var example3 = new String("Hello World");
+console.log(typeof example3); // object
+console.log(typeof emulateMessage(example3)); // string
+
+// test #4
+var example4 = {
+    "name": "John Smith",
+    "age": 43
+};
+console.log(typeof example4); // object
+console.log(typeof emulateMessage(example4)); // object
+
+// test #5
+function Animal (sType, nAge) {
+    this.type = sType;
+    this.age = nAge;
+}
+var example5 = new Animal("Cat", 3);
+alert(example5.constructor); // Animal
+alert(emulateMessage(example5).constructor); // Object
+ +

Значения, которые клонируются и совместно не используются, называются сообщениями. Как вы, возможно, знаете, сообщения могут быть отправлены в главную страницу и из нее, используя postMessage(), и {{domxref("MessageEvent.data", "data")}}, содержа данные, передаваемые из worker-а.

+ +

example.html: (главная страница):

+ +
var myWorker = new Worker("my_task.js");
+
+myWorker.onmessage = function (oEvent) {
+  console.log("Worker said : " + oEvent.data);
+};
+
+myWorker.postMessage("ali");
+ +

my_task.js (worker):

+ +
postMessage("I\'m working before postMessage(\'ali\').");
+
+onmessage = function (oEvent) {
+  postMessage("Hi " + oEvent.data);
+};
+ +

Алгоритм структурированного клонирования может принять JSON и некоторые вещи, которые JSON не может принять, например, циклические ссылки.

+ +

Примеры передачи данных

+ +

Пример #1: Расширенная передача JSON данных и создание системы коммутации

+ +

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

+ +

В первую очередь мы создаем класс QueryableWorker, который принимает url worker-а, стандартный обработчик событий (defaultListener) и обработчик ошибок. Этот класс будет отслеживать всех обработчиков и поможет нам общаться с воркером.

+ +
function QueryableWorker(url, defaultListener, onError) {
+    var instance = this,
+        worker = new Worker(url),
+        listeners = {};
+
+    this.defaultListener = defaultListener || function() {};
+
+    if (onError) {worker.onerror = onError;}
+
+    this.postMessage = function(message) {
+        worker.postMessage(message);
+    }
+
+    this.terminate = function() {
+        worker.terminate();
+    }
+}
+
+ +

Затем мы добавляем методы добавления/удаления обработчиков.

+ +
this.addListeners = function(name, listener) {
+    listeners[name] = listener;
+}
+
+this.removeListeners = function(name) {
+    delete listeners[name];
+}
+
+ +

Здесь мы создадим у worker-а два простых события для примера: получение разницы двух чисел и создание оповещения через три секунды. Но сначала нам нужно реализовать метод sendQuery, который проверит есть ли вообще у worker-а обработчик, который мы собираемся вызвать.

+ +
/*
+  Эта функция принимает по крайней мере один аргумент: имя метода, который мы хотим вызвать.
+  Далее мы можем передать методу необходимые ему аргументы.
+ */
+this.sendQuery = function() {
+    if (arguments.length < 1) {
+         throw new TypeError('QueryableWorker.sendQuery takes at least one argument');
+         return;
+    }
+    worker.postMessage({
+        'queryMethod': arguments[0],
+        'queryArguments': Array.prototype.slice.call(arguments, 1)
+    });
+}
+
+ +

Завершим QueryableWorker методом onmessage.  Если worker имеет соответствующий метод, который мы запросили, он также должен вернуть соответствующий обработчик и аргументы, которые нам нужны. Останется лишь найти его в listeners:

+ +
worker.onmessage = function(event) {
+    if (event.data instanceof Object &&
+        event.data.hasOwnProperty('queryMethodListener') &&
+        event.data.hasOwnProperty('queryMethodArguments')) {
+        listeners[event.data.queryMethodListener].apply(instance, event.data.queryMethodArguments);
+    } else {
+        this.defaultListener.call(instance, event.data);
+    }
+}
+
+ +

Теперь к самому worker-у. Сначала следует определить эти два простых метода:

+ +
var queryableFunctions = {
+    getDifference: function(a, b) {
+        reply('printStuff', a - b);
+    },
+    waitSomeTime: function() {
+        setTimeout(function() {
+            reply('doAlert', 3, 'seconds');
+        }, 3000);
+    }
+}
+
+function reply() {
+    if (arguments.length < 1) {
+        throw new TypeError('reply - takes at least one argument');
+        return;
+    }
+    postMessage({
+        queryMethodListener: arguments[0],
+        queryMethodArguments: Array.prototype.slice.call(arguments, 1)
+    });
+}
+
+/* This method is called when main page calls QueryWorker's postMessage method directly*/
+function defaultReply(message) {
+    // do something
+}
+
+ +

И onmessage:

+ +
onmessage = function(event) {
+    if (event.data instanceof Object &&
+        event.data.hasOwnProperty('queryMethod') &&
+        event.data.hasOwnProperty('queryMethodArguments')) {
+        queryableFunctions[event.data.queryMethod]
+            .apply(self, event.data.queryMethodArguments);
+    } else {
+        defaultReply(event.data);
+    }
+}
+ +

Полный код примера:

+ +

example.html (основная страница):

+ +
<!doctype html>
+  <html>
+    <head>
+      <meta charset="UTF-8"  />
+      <title>MDN Example - Queryable worker</title>
+    <script type="text/javascript">
+    /*
+      QueryableWorker instances methods:
+        * sendQuery(queryable function name, argument to pass 1, argument to pass 2, etc. etc): calls a Worker's queryable function
+        * postMessage(string or JSON Data): see Worker.prototype.postMessage()
+        * terminate(): terminates the Worker
+        * addListener(name, function): adds a listener
+        * removeListener(name): removes a listener
+      QueryableWorker instances properties:
+        * defaultListener: the default listener executed only when the Worker calls the postMessage() function directly
+     */
+    function QueryableWorker(url, defaultListener, onError) {
+      var instance = this,
+      worker = new Worker(url),
+      listeners = {};
+
+      this.defaultListener = defaultListener || function() {};
+
+      if (onError) {worker.onerror = onError;}
+
+      this.postMessage = function(message) {
+        worker.postMessage(message);
+      }
+
+      this.terminate = function() {
+        worker.terminate();
+      }
+
+      this.addListener = function(name, listener) {
+        listeners[name] = listener;
+      }
+
+      this.removeListener = function(name) {
+        delete listeners[name];
+      }
+
+      /*
+        This functions takes at least one argument, the method name we want to query.
+        Then we can pass in the arguments that the method needs.
+      */
+      this.sendQuery = function() {
+        if (arguments.length < 1) {
+          throw new TypeError('QueryableWorker.sendQuery takes at least one argument');
+          return;
+        }
+        worker.postMessage({
+          'queryMethod': arguments[0],
+          'queryMethodArguments': Array.prototype.slice.call(arguments, 1)
+        });
+      }
+
+      worker.onmessage = function(event) {
+        if (event.data instanceof Object &&
+          event.data.hasOwnProperty('queryMethodListener') &&
+          event.data.hasOwnProperty('queryMethodArguments')) {
+          listeners[event.data.queryMethodListener].apply(instance, event.data.queryMethodArguments);
+        } else {
+          this.defaultListener.call(instance, event.data);
+        }
+      }
+    }
+
+    // your custom "queryable" worker
+    var myTask = new QueryableWorker('my_task.js');
+
+    // your custom "listeners"
+    myTask.addListener('printStuff', function (result) {
+      document.getElementById('firstLink').parentNode.appendChild(document.createTextNode('The difference is ' + result + '!'));
+    });
+
+    myTask.addListener('doAlert', function (time, unit) {
+      alert('Worker waited for ' + time + ' ' + unit + ' :-)');
+    });
+</script>
+</head>
+<body>
+  <ul>
+    <li><a id="firstLink" href="javascript:myTask.sendQuery('getDifference', 5, 3);">What is the difference between 5 and 3?</a></li>
+    <li><a href="javascript:myTask.sendQuery('waitSomeTime');">Wait 3 seconds</a></li>
+    <li><a href="javascript:myTask.terminate();">terminate() the Worker</a></li>
+  </ul>
+</body>
+</html>
+ +

my_task.js (код worker-а):

+ +
var queryableFunctions = {
+  // пример #1: получить разницу между двумя числами
+  getDifference: function(nMinuend, nSubtrahend) {
+      reply('printStuff', nMinuend - nSubtrahend);
+  },
+  // пример #2: подождать три секунды
+  waitSomeTime: function() {
+      setTimeout(function() { reply('doAlert', 3, 'seconds'); }, 3000);
+  }
+};
+
+// системные функции
+
+function defaultReply(message) {
+  // your default PUBLIC function executed only when main page calls the queryableWorker.postMessage() method directly
+  // do something
+}
+
+function reply() {
+  if (arguments.length < 1) { throw new TypeError('reply - not enough arguments'); return; }
+  postMessage({ 'queryMethodListener': arguments[0], 'queryMethodArguments': Array.prototype.slice.call(arguments, 1) });
+}
+
+onmessage = function(oEvent) {
+  if (oEvent.data instanceof Object && oEvent.data.hasOwnProperty('queryMethod') && oEvent.data.hasOwnProperty('queryMethodArguments')) {
+    queryableFunctions[oEvent.data.queryMethod].apply(self, oEvent.data.queryMethodArguments);
+  } else {
+    defaultReply(oEvent.data);
+  }
+};
+
+ +

Можно переключать содержимое каждой главной страницы -> worker и worker -> сообщение главной страницы. И имена свойств "queryMethod", "queryMethodListeners", "queryMethodArguments" могут быть любыми пока они согласуются с QueryableWorker и worker.

+ +

Передача данных с помощью передачи владения (передаваемые объекты)

+ +

Google Chrome 17+ and Firefox 18+ имеют дополнительную возможность передачи определенных типов объектов (передаваемые объекты реализующие {{domxref("Transferable")}} интерфейс) к или из worker-а с высокой призводительностью. Эти объекты передаются из одного контекста в другой без операций копирования, что приводит к значительному повышению производительности при отправке больших наборов данных. Думайте об этом как о передаче по ссылке в мире C/C++. Однако в отличии от передачи по ссылке, "версия" из вызывающего контекста больше недоступна после передачи. Владельцем становится новый контекст.  Для примера, после передачи {{domxref("ArrayBuffer")}} из главной страницы к worker-у,  исходный {{domxref("ArrayBuffer")}} очищается и более недоступен для использования.  Его содержание (в буквальном смысле) переносится в рабочий контекст.

+ +
// Create a 32MB "file" and fill it.
+var uInt8Array = new Uint8Array(1024*1024*32); // 32MB
+for (var i = 0; i < uInt8Array.length; ++i) {
+  uInt8Array[i] = i;
+}
+
+worker.postMessage(uInt8Array.buffer, [uInt8Array.buffer]);
+
+ +
+

Заметка: Для дополнительной информации о передаваемых объектах, производительности и поддержки для этого метода, читайте  Transferable Objects: Lightning Fast! на HTML5 Rocks.

+
+ +

Встроенные worker-ы

+ +

Не существует утвержденного способа встроить код worker-а в рамках веб-страницы, как элемент {{HTMLElement("script")}} делает для обычных скриптов. Но элемент {{HTMLElement("script")}}, который не имеет аттрибута src и аттрибута  type, которому не назначен выполняемый MIME type, можно считать блоком данных для использования JavaScript. Блок данных "Data blocks" — это более общее свойство HTML5, может содержать любые текстовые данные. Так, worker может быть встроен следующим образом:

+ +
<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8" />
+<title>MDN Example - Embedded worker</title>
+<script type="text/js-worker">
+  // Этот script НЕ БУДЕТ анализироваться JS движками, потому что  его MIME-тип text/js-worker.
+  var myVar = 'Hello World!';
+  // Остальная часть кода вашего воркера идет сюда.
+</script>
+<script type="text/javascript">
+  // Этот script БУДЕТ проанализирован JS движкам, потому что его MIME-тип text/javascript.
+  function pageLog(sMsg) {
+    // Use a fragment: browser will only render/reflow once.
+    var oFragm = document.createDocumentFragment();
+    oFragm.appendChild(document.createTextNode(sMsg));
+    oFragm.appendChild(document.createElement('br'));
+    document.querySelector('#logDisplay').appendChild(oFragm);
+  }
+</script>
+<script type="text/js-worker">
+  // Этот script НЕ БУДЕТ анализироваться JS движками, потому что его MIME-тип text/js-worker.
+  onmessage = function(oEvent) {
+    postMessage(myVar);
+  };
+  // Остальная часть кода вашего воркера идет сюда.
+</script>
+<script type="text/javascript">
+  // Этот script БУДЕТ проанализирован JS движкам, потому что его MIME-тип text/javascript.
+
+  // В прошлом...:
+  // blob builder существовал
+  // ... но теперь мы используем Blob...:
+  var blob = new Blob(Array.prototype.map.call(document.querySelectorAll('script[type=\'text\/js-worker\']'), function (oScript) { return oScript.textContent; }),{type: 'text/javascript'});
+
+  // Создание нового свойства document.worker, содержащего все наши "text/js-worker" скрипты.
+  document.worker = new Worker(window.URL.createObjectURL(blob));
+
+  document.worker.onmessage = function(oEvent) {
+    pageLog('Received: ' + oEvent.data);
+  };
+
+  // Запуск воркера.
+  window.onload = function() { document.worker.postMessage(''); };
+</script>
+</head>
+<body><div id="logDisplay"></div></body>
+</html>
+
+ +
Встраиваемый worker теперь внесен в новое custom свойство document.worker
+ +
+ +
Также стоит отметить, что вы также можете преобразовать функцию в BLOB-объект, а затем сгенерировать URL объекта из этого BLOB-объекта. Например:
+ +
function fn2workerURL(fn) {
+  var blob = new Blob(['('+fn.toString()+')()'], {type: 'application/javascript'})
+  return URL.createObjectURL(blob)
+}
+
+ +

Другие примеры

+ +

В этой секции представлено еще несколько примеров как использовать worker-ы.

+ +

Выполнение вычислений в фоне

+ +

Worker-ы в основном полезны для того, чтобы позволить вашему коду выполнять ресурсоемкие вычисления, не блокируя поток пользовательского интерфейса. В этом примере, worker используется для вычисления числа Фибоначчи.

+ +

Код JavaScript

+ +

Следующий код JavaScript хранится в файле "fibonacci.js", на который ссылается HTML в следующем разделе.

+ +
var results = [];
+
+function resultReceiver(event) {
+  results.push(parseInt(event.data));
+  if (results.length == 2) {
+    postMessage(results[0] + results[1]);
+  }
+}
+
+function errorReceiver(event) {
+  throw event.data;
+}
+
+onmessage = function(event) {
+  var n = parseInt(event.data);
+
+  if (n == 0 || n == 1) {
+    postMessage(n);
+    return;
+  }
+
+  for (var i = 1; i <= 2; i++) {
+    var worker = new Worker("fibonacci.js");
+    worker.onmessage = resultReceiver;
+    worker.onerror = errorReceiver;
+    worker.postMessage(n - i);
+  }
+ };
+ +

Worker устанавливает свойство onmessage для функции,  которая будет получать сообщения, отправленные при вызове postMessage() рабочего объекта (обратите внимание, что это отличается от определения глобальной переменной с таким именем или определения функции с таким именем. var onmessage и function onmessage будет определять глобальные свойства с этими именами , но они не будут регистрировать функцию для получения сообщений, отправленных веб-страницей, которая создала worker). Это запускает рекурсию, порождая новые копии для обработки каждой итерации вычисления.

+ +

HTML код

+ +
<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="UTF-8"  />
+    <title>Test threads fibonacci</title>
+  </head>
+  <body>
+
+  <div id="result"></div>
+
+  <script language="javascript">
+
+    var worker = new Worker('fibonacci.js');
+
+    worker.onmessage = function(event) {
+      document.getElementById('result').textContent = event.data;
+      dump('Got: ' + event.data + '\n');
+    };
+
+    worker.onerror = function(error) {
+      dump('Worker error: ' + error.message + '\n');
+      throw error;
+    };
+
+    worker.postMessage('5');
+
+  </script>
+  </body>
+</html>
+ +

Веб-страница создает элемент div с ID result , который используется для отображения результата, а затем порождает worker. После порождения worker-а, обработчик onmessage настроен для отображения результатов путем установки содержимого элемента div, и обработчик onerror настроен на выброс сообщения об ошибке.

+ +

Наконец, сообщение отправляется worker-у, чтобы запустить его.

+ +

Попробуйте этот пример.

+ +

Выполнение веб I/O в фоне

+ +

Вы можете найти пример этого в статье Использование worker-ов в расширениях.

+ +

Разделение задач между множественными worker-ами

+ +

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

+ +

Другие типы worker-ов

+ +

В дополнение к выделенным и совместно используемым web worker-ам доступны другие типы worker-ов:

+ + + +

Функции и интерфейсы доступные в worker-ах

+ +

Внутри web worker-а вы можете использовать большинство стандартных функций JavaScript, включая:

+ + + +

Главное, что вы не можете сделать в Worker это напрямую повлиять на родительскую страницу. Это включает в себя манипулирование DOM и использование объектов этой страницы. Вы должны сделать это косвенно, отправив сообщение обратно основному сценарию через {{domxref("DedicatedWorkerGlobalScope.postMessage")}}, а затем выполнив изменения оттуда.

+ +
+

Заметка: Для знакомства с  полным списком функций,  доступных для worker-ов, смотрите статью Функции и интерфейсы доступные worker-ам.

+
+ +

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

+ + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('HTML WHATWG', '#toc-workers')}}{{Spec2('HTML WHATWG')}}Без изменений {{SpecName("Web Workers")}}.
{{SpecName('Web Workers')}}{{Spec2('Web Workers')}}Начальное определение.
+ +

Браузерная совместимость

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support4[1]{{CompatGeckoDesktop("1.9.1")}}10.010.6[1]4[2]
Shared workers4[1]{{CompatGeckoDesktop(29)}}{{CompatNo}}10.65
+ {{CompatNo}} 6.1[4]
Passing data using structured cloning13{{CompatGeckoDesktop(8)}}10.011.56
Passing data using transferable objects17 {{property_prefix("webkit")}}
+ 21
{{CompatGeckoDesktop(18)}}{{CompatNo}}156
Global {{domxref("window.URL", "URL")}}10[3]
+ 23
{{CompatGeckoDesktop(21)}}11156[3]
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)Firefox OS (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support4.44[1]3.51.0.110.011.5[1]5.1[2]
Shared workers{{CompatNo}}4[1]81.0.1{{CompatNo}}{{CompatNo}}{{CompatNo}}
Passing data using structured cloning{{CompatNo}}481.0.1{{CompatNo}}{{CompatNo}}{{CompatNo}}
Passing data using transferable objects{{CompatNo}}{{CompatNo}}181.0.1{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

[1] Chrome и Opera выдают ошибку "Uncaught SecurityError: Failed to construct 'Worker': Script at 'file:///Path/to/worker.js' cannot be accessed from origin 'null'." когда вы пытаетесь запустить worker локально. Нужно быть на надлежащем домене.

+ +

[2] Начиная с Safari 7.1.2, вы можете вызывать console.log изнутри worker-а, но он ничего не выведет в консоль. Более старые версии Safari не ползволяют вызывать console.log изнутри worker-а

+ +

[3] Эта функция реализована с префиксом как webkitURL.

+ +

[4] Safari удалил поддержку SharedWorker.

+ +

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

+ + diff --git a/files/ru/dom/window.requestanimationframe/index.html b/files/ru/dom/window.requestanimationframe/index.html new file mode 100644 index 0000000000..d451cae62f --- /dev/null +++ b/files/ru/dom/window.requestanimationframe/index.html @@ -0,0 +1,92 @@ +--- +title: window.requestAnimationFrame() +slug: DOM/window.requestAnimationFrame +tags: + - Анимация +translation_of: Web/API/window/requestAnimationFrame +--- +
{{APIRef}}
+ +

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

+ +
Заметка: Ваш callback метод сам должен вызвать requestAnimationFrame() иначе анимация остановится.
+ +

Вы должны вызывать этот метод всякий раз, когда готовы обновить анимацию на экране, чтобы запросить планирование анимации. Обычно запросы происходят 60 раз в секунду, но чаще всего совпадают с частотой обновления экрана. В большинстве браузеров в фоновых вкладках или скрытых <iframe>, вызовы requestAnimationFrame() приостанавливаются, для того, чтобы повысить производительность и время работы батареи.

+ +

Callback методу передаётся один аргумент, {{domxref("DOMHighResTimeStamp")}}, который содержит текущее время (количество миллисекунд, прошедших с момента time origin). Когда callback-и, отправленные в очередь с помощью requestAnimationFrame() начинают вызывать несколько callback-ов в одном кадре, каждый получает одинаковый timestamp, хотя для вычисления каждого callback было затрачено время. Этот timestamp - десятичное число в миллисекундах, но с минимальной точностью в 1ms (1000 µs).

+ +

Синтаксис

+ +
window.requestAnimationFrame(callback);
+ +

Параметры

+ +
+
callback
+
Функция, которая будет вызвана, когда придёт время обновить вашу анимацию на следующей перерисовке.
+
element {{ optional_inline() }}
+
Необязательный параметр (не используется в Firefox или IE), определяющий элемент, который визуально содержит всю анимацию. Для canvas'а и WebGL'a им должен быть {{ HTMLElement("canvas") }}. Для других элементов вы можете опустить этот параметр для чуть лучшего пользовательского опыта.
+
+ +

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

+ +

requestID — длинное целое, являющееся уникальным идентификатором для записи, содержащей callback. Оно не равно нулю, но других предположений о его значении делать не следует. Вы можете передать его в {{ domxref("window.cancelAnimationFrame()") }} для отмены вызова.

+ +

Пример

+ +
var start = null;
+var element = document.getElementById('SomeElementYouWantToAnimate');
+
+function step(timestamp) {
+  if (!start) start = timestamp;
+  var progress = timestamp - start;
+  element.style.transform = 'translateX(' + Math.min(progress / 10, 200) + 'px)';
+  if (progress < 2000) {
+    window.requestAnimationFrame(step);
+  }
+}
+
+window.requestAnimationFrame(step);
+ +

Примечание

+ +

В Edge версиях младше 17 и в Internet Explorer не надежно запускать requestAnimationFrame перед циклом рисования.

+ +

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

+ + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('HTML WHATWG', '#animation-frames', 'requestAnimationFrame')}}{{Spec2('HTML WHATWG')}}Без изменений, заменяет предыдущую.
{{SpecName('RequestAnimationFrame', '#dom-windowanimationtiming-requestanimationframe', 'requestAnimationFrame')}}{{Spec2('RequestAnimationFrame')}}Первоначальное описание.
+ +

Браузерная совместимость

+ +

{{Compat("api.Window.requestAnimationFrame")}}

+ +

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

+ + -- cgit v1.2.3-54-g00ecf