renovations
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 59 KiB |
Before Width: | Height: | Size: 176 KiB After Width: | Height: | Size: 170 KiB |
|
@ -0,0 +1,41 @@
|
|||
В стандартном режиме IE8 можно получить текущую прокрутку так:
|
||||
|
||||
```js
|
||||
//+ run
|
||||
alert( document.documentElement.scrollTop );
|
||||
```
|
||||
|
||||
Самым простым, но неверным было бы такое решение:
|
||||
```js
|
||||
//+ run
|
||||
// "полифилл"
|
||||
window.pageYOffset = document.documentElement.scrollTop;
|
||||
|
||||
// использование "полифилла"
|
||||
alert( window.pageYOffset );
|
||||
```
|
||||
|
||||
Код выше не учитывает текущую прокрутку. Он присваивает `window.pageYOffset` один раз и в дальнейшем, чтобы получить текущую прокрутку, нужно снова обратиться к `document.documentElement.scrollTop` не меняет его. А задача как раз -- сделать полифилл, то есть дать возможность использовать `window.pageYOffset` для получения текущего состояния прокрутки без "танцев бубном", так же как в современных браузерах.
|
||||
|
||||
Для этого создадим свойство через геттер.
|
||||
|
||||
В IE8 для DOM-объектов работает `Object.defineProperty`:
|
||||
|
||||
```js
|
||||
//+ run
|
||||
// полифилл
|
||||
Object.defineProperty(window, 'pageYOffset', {
|
||||
get: function() {
|
||||
return document.documentElement.scrollTop;
|
||||
}
|
||||
});
|
||||
|
||||
// использование полифилла
|
||||
alert( window.pageYOffset );
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
# Полифилл для pageYOffset в IE8
|
||||
|
||||
[importance 3]
|
||||
|
||||
Обычно в IE8 не поддерживается свойство `pageYOffset`. Напишите полифилл для него.
|
||||
|
||||
При подключённом полифилле такой код должен работать в IE8:
|
||||
|
||||
```js
|
||||
// текущая прокрутка страницы в IE8
|
||||
alert( window.pageYOffset );
|
||||
```
|
|
@ -107,9 +107,9 @@ function getOffsetSum(elem) {
|
|||
var top = 0, left = 0;
|
||||
|
||||
while(elem) {
|
||||
top = top + parseInt(elem.offsetTop);
|
||||
left = left + parseInt(elem.offsetLeft);
|
||||
elem = elem.offsetParent;
|
||||
top = top + parseInt(elem.offsetTop);
|
||||
left = left + parseInt(elem.offsetLeft);
|
||||
elem = elem.offsetParent;
|
||||
}
|
||||
|
||||
return {top: top, left: left};
|
||||
|
|
|
@ -1,35 +1,50 @@
|
|||
# Итого
|
||||
|
||||
В этой главе кратко перечислены основные свойства и методы DOM, которые мы изучили.
|
||||
В этой главе кратко перечислены основные свойства и методы DOM, которые мы изучили. Их уже довольно много.
|
||||
|
||||
Используйте её, чтобы получить быстрый итоговый обзор того, что изучали ранее.
|
||||
Используйте её, чтобы по-быстрому вспомнить и прокрутить в голове то, что изучали ранее. Все ли эти свойства вам знакомы?
|
||||
|
||||
Кое-где стоит ограничение на версии IE, но на все свойства можно найти или сделать или найти полифилл, с которым их можно использовать везде.
|
||||
|
||||
[cut]
|
||||
|
||||
## Создание
|
||||
|
||||
<dl>
|
||||
<dt>`document.createElement(tag)`</dt><dd>создать элемент с тегом `tag`</dd>
|
||||
<dt>`document.createTextNode(txt)`</dt><dd>создать текстовый узел с текстом `txt`</dd>
|
||||
<dt>`node.cloneNode(deep)`</dt><dd>клонировать существующий узел, если `deep=false`, то без потомков.</dd>
|
||||
<dt>`document.createElement(tag)`</dt><dd>Создать элемент с тегом `tag`</dd>
|
||||
<dt>`document.createTextNode(txt)`</dt><dd>Создать текстовый узел с текстом `txt`</dd>
|
||||
<dt>`node.cloneNode(deep)`</dt><dd>Клонировать существующий узел, если `deep=false`, то без потомков.</dd>
|
||||
</dl>
|
||||
|
||||
## Свойства узлов
|
||||
|
||||
<dl>
|
||||
<dt>`node.nodeType`</dt><dd>тип узла: 1(элемент) / 3(текст) / другие.</dd>
|
||||
<dt>`elem.tagName`</dt><dd>тег элемента.</dd>
|
||||
<dt>`node.nodeType`</dt><dd>Тип узла: 1(элемент) / 3(текст) / другие.</dd>
|
||||
<dt>`elem.tagName`</dt><dd>Тег элемента.</dd>
|
||||
<dt>`elem.innerHTML`</dt><dd>HTML внутри элемента.</dd>
|
||||
<dt>`node.data`</dt><dd>содержимое любого узла любого типа, кроме элемента.</dd>
|
||||
<dt>`elem.outerHTML`</dt><dd>Весь HTML элемента, включая сам тег. На запись использовать с осторожностью, так как не модифицирует элемент, а вставляет новый вместо него.</dd>
|
||||
<dt>`node.data` / `node.nodeValue`</dt><dd>Содержимое узла любого типа, кроме элемента.</dd>
|
||||
<dt>`node.textContent`</dt><dd>Текстовое содержимое узла, для элементов содержит текст с вырезанными тегами (IE9+).</dd>
|
||||
<dt>`elem.hidden`</dt><dd>Если поставить `true`, то элемент будет скрыт (IE10+).</dd>
|
||||
</dl>
|
||||
|
||||
## Атрибуты
|
||||
|
||||
<dl>
|
||||
<dt>`elem.getAttribute(name)`, `elem.hasAttribute(name)`, `elem.setAttribute(name, value)`</dt>
|
||||
<dd>Чтение атрибута, проверка наличия и запись.</dd>
|
||||
<dt>`elem.dataset.*`</dt><dd>Значения атрибутов вида `data-*` (IE10+).</dd>
|
||||
</dl>
|
||||
|
||||
## Ссылки
|
||||
|
||||
<dl>
|
||||
<dt>`document.documentElement`</dt>
|
||||
<dd>элемент `<HTML>`</dd>
|
||||
<dd>Элемент `<HTML>`</dd>
|
||||
<dt>`document.body`</dt>
|
||||
<dd>элемент `<BODY>`</dd>
|
||||
<dd>Элемент `<BODY>`</dd>
|
||||
<dt>`document.head`</dt>
|
||||
<dd>Элемент `<HEAD>` (IE9+)</dd>
|
||||
</dl>
|
||||
|
||||
По всем узлам:
|
||||
|
@ -42,14 +57,15 @@
|
|||
Только по элементам:
|
||||
|
||||
<ul>
|
||||
<li>`children`</li>
|
||||
<li>`parentElement`</li>
|
||||
<li>`nextElementSibling` `previousElementSibling`</li>
|
||||
<li>`firstElementChild` `lastElementChild`</li>
|
||||
<li>`children`, `firstElementChild` `lastElementChild`</li>
|
||||
</ul>
|
||||
|
||||
В IE8- из них работает только `children`, причём содержит не только элементы, но и комментарии (ошибка в браузере).
|
||||
Все они IE9+, кроме `children`, который работает в IE8-, но содержит не только элементы, но и комментарии (ошибка в браузере).
|
||||
|
||||
### Таблицы
|
||||
Дополнительно у некоторых типов элементов могут быть и другие ссылки, свойства, коллекции для навигации,
|
||||
например для таблиц:
|
||||
|
||||
<dl>
|
||||
<dt>`table.rows[N]`</dt>
|
||||
|
@ -62,17 +78,6 @@
|
|||
<dd>номер ячейки в строке.</dd>
|
||||
</dl>
|
||||
|
||||
### Формы
|
||||
|
||||
<dl>
|
||||
<dt>`document.forms[N/name]`</dt>
|
||||
<dd>форма по номеру/имени.</dd>
|
||||
<dt>`form.elements[N/name]`</dt>
|
||||
<dd>элемент формы по номеру/имени</dd>
|
||||
<dt>`element.form`</dt>
|
||||
<dd>форма для элемента.</dd>
|
||||
</dl>
|
||||
|
||||
## Поиск
|
||||
|
||||
|
||||
|
@ -84,16 +89,28 @@
|
|||
<dt>`document.getElementById(id)`</dt>
|
||||
<dd>По уникальному `id`</dd>
|
||||
<dt>`document.getElementsByName(name)`</dt>
|
||||
<dd>По атрибуту `name`, в IE<10 работает только для элементов, где `name` предусмотрен стандартом.</dd>
|
||||
<dd>По атрибуту `name`, в IE9- работает только для элементов, где `name` предусмотрен стандартом.</dd>
|
||||
<dt>`*.getElementsByTagName(tag)`</dt>
|
||||
<dd>По тегу `tag`</dd>
|
||||
<dt>`*.getElementsByClassName(class)`</dt>
|
||||
<dd>По классу, IE9+, корректно работает с элементами, у которых несколько классов.</dd>
|
||||
</dl>
|
||||
|
||||
При поддержки IE только версии 8 и выше, можно использовать только `querySelector/querySelectorAll`.
|
||||
Если не нужно поддерживать IE7-, то можно использовать только `querySelector/querySelectorAll`. Методы `getElement*` работают быстрее (за счёт более оптимальной внутренней реализации), но в 99% случаев это различие очень небольшое и роли не играет.
|
||||
|
||||
Дополнительно есть методы:
|
||||
<dl>
|
||||
<dt>`elem.matches(css)`</dt>
|
||||
<dd>Проверяет, подходит ли элемент под CSS-селектор.</dd.
|
||||
<dt>`elem.closest(css)`</dt>
|
||||
<dd>Ищет ближайший элемент сверху по иерархии DOM, подходящий под CSS-селектор. Первым проверяется сам `elem`. Этот элемент возвращается.</dd>
|
||||
<dt>`elemA.contains(elemB)`</dt>
|
||||
<dd>Возвращает `true`, если `elemA` является предком (содержит) `elemB`.</dd>
|
||||
<dt>`elemA.compareDocumentPosition(elemB)`</dt>
|
||||
<dd>Возвращает битовую маску, которая включает в себя отношение вложенности между `elemA` и `elemB`, а также -- какой из элементов появляется в DOM первым.</dd>
|
||||
|
||||
</dl>
|
||||
|
||||
Для более старых IE нужен либо фреймворк, который сам умеет искать узлы по селектору, наподобие jQuery, либо пользоваться методами `get*`, все из которых, кроме `...ByClassName`, поддерживаются с древних времён.
|
||||
|
||||
## Изменение
|
||||
|
||||
|
@ -102,6 +119,19 @@
|
|||
<li>`parent.removeChild(child)`</li>
|
||||
<li>`parent.insertBefore(newChild, refNode)`</li>
|
||||
<li>`parent.insertAdjacentHTML("beforeBegin|afterBegin|beforeEnd|afterEnd", html)`</li>
|
||||
<li>`parent.insertAdjacentElement("beforeBegin|...|afterEnd", text)` (кроме FF)</li>
|
||||
<li>`parent.insertAdjacentText("beforeBegin|...|afterEnd", text)` (кроме FF)</li>
|
||||
<li>`document.write(...)`</li>
|
||||
</ul>
|
||||
|
||||
Скорее всего, понадобятся полифиллы для:
|
||||
|
||||
<ul>
|
||||
<li>`node.append(...nodes)`</li>
|
||||
<li>`node.prepend(...nodes)`</li>
|
||||
<li>`node.after(...nodes)`,</li>
|
||||
<li>`node.before(...nodes)`</li>
|
||||
<li>`node.replaceWith(...nodes)`</li>
|
||||
</ul>
|
||||
|
||||
## Классы и стили
|
||||
|
@ -110,7 +140,7 @@
|
|||
<dt>`elem.className`</dt>
|
||||
<dd>Атрибут `class`</dt>
|
||||
<dt>`elem.classList.add(class) remove(class) toggle(class) contains(class)`</dt>
|
||||
<dd>Управление классами в HTML5, для IE8+ есть [эмуляция](https://github.com/eligrey/classList.js/blob/master/classList.js).</dd>
|
||||
<dd>Управление классами, для IE9- есть [эмуляция](https://github.com/eligrey/classList.js/blob/master/classList.js).</dd>
|
||||
<dt>`elem.style`</dt>
|
||||
<dd>Стили в атрибуте `style` элемента</dd>
|
||||
<dt>`getComputedStyle(elem, "")`</dd>
|
||||
|
|
|
@ -23,7 +23,7 @@ DOM позволяет делать что угодно с HTML-элементо
|
|||
<dd>Вторая точка входа -- `document.body`, который соответствует тегу `<body>`.</dd>
|
||||
</dl>
|
||||
|
||||
В современных браузерах (кроме старых IE) также действует `document.head` -- прямой доступ к `<head>`
|
||||
В современных браузерах (кроме IE8-) также есть `document.head` -- прямая ссылка на `<head>`
|
||||
|
||||
[warn header="Есть одна тонкость: `document.body` может быть равен `null`"]
|
||||
Нельзя получить доступ к элементу, которого еще не существует в момент выполнения скрипта.
|
||||
|
|
|
@ -6,9 +6,11 @@
|
|||
<defs></defs>
|
||||
<g id="combined" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
|
||||
<g id="dom-links-elements.svg" sketch:type="MSArtboardGroup">
|
||||
<rect id="Rectangle-8" stroke="#E8C48E" stroke-width="4" fill="#FFF9EB" sketch:type="MSShapeGroup" x="131" y="5" width="194" height="24"></rect>
|
||||
<text id="document.documentEle" sketch:type="MSTextLayer" font-family="Consolas" font-size="14" font-weight="bold" sketch:alignment="middle" fill="#8A704D">
|
||||
<tspan x="137.692383" y="22">document.documentElement <HTML></tspan>
|
||||
</text>
|
||||
<rect id="Rectangle-7" stroke="#E8C48E" stroke-width="4" fill="#FFF9EB" sketch:type="MSShapeGroup" x="165" y="73" width="113" height="24"></rect>
|
||||
<text id="document.body-(если-" sketch:type="MSTextLayer" font-family="Consolas" font-size="14" font-weight="bold" sketch:alignment="middle" fill="#8A704D">
|
||||
<tspan x="172.84375" y="90">document.body (если внутри body)</tspan>
|
||||
</text>
|
||||
|
@ -21,8 +23,6 @@
|
|||
<tspan x="221.183594" y="165" fill="#EE6B47">Element</tspan>
|
||||
</text>
|
||||
<rect id="Rectangle-6" stroke="#E8C48E" stroke-width="4" fill="#FFF9EB" sketch:type="MSShapeGroup" x="183" y="208" width="75" height="24"></rect>
|
||||
<rect id="Rectangle-7" stroke="#E8C48E" stroke-width="4" fill="#FFF9EB" sketch:type="MSShapeGroup" x="165" y="73" width="113" height="24"></rect>
|
||||
<rect id="Rectangle-8" stroke="#E8C48E" stroke-width="4" fill="#FFF9EB" sketch:type="MSShapeGroup" x="131" y="5" width="194" height="24"></rect>
|
||||
<text id="<DIV>" sketch:type="MSTextLayer" font-family="Open Sans" font-size="14" font-weight="526" sketch:alignment="middle" fill="#8A704D">
|
||||
<tspan x="201.051859" y="225"><DIV></tspan>
|
||||
</text>
|
||||
|
|
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 9.8 KiB |
|
@ -6,6 +6,9 @@
|
|||
<defs></defs>
|
||||
<g id="combined" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
|
||||
<g id="dom-links.svg" sketch:type="MSArtboardGroup">
|
||||
<rect id="Rectangle-9" stroke="#E8C48E" stroke-width="4" fill="#FFF9EB" sketch:type="MSShapeGroup" x="153" y="2" width="113" height="24"></rect>
|
||||
<rect id="Rectangle-7" stroke="#E8C48E" stroke-width="4" fill="#FFF9EB" sketch:type="MSShapeGroup" x="153" y="136" width="113" height="24"></rect>
|
||||
<rect id="Rectangle-8" stroke="#E8C48E" stroke-width="4" fill="#FFF9EB" sketch:type="MSShapeGroup" x="119" y="68" width="194" height="24"></rect>
|
||||
<text id="document" sketch:type="MSTextLayer" font-family="Consolas" font-size="14" font-weight="bold" sketch:alignment="middle" fill="#8A704D">
|
||||
<tspan x="177.710938" y="18">document</tspan>
|
||||
</text>
|
||||
|
@ -25,9 +28,6 @@
|
|||
<tspan x="172" y="228">parentNode</tspan>
|
||||
</text>
|
||||
<rect id="Rectangle-6" stroke="#E8C48E" stroke-width="4" fill="#FFF9EB" sketch:type="MSShapeGroup" x="171" y="271" width="75" height="24"></rect>
|
||||
<rect id="Rectangle-7" stroke="#E8C48E" stroke-width="4" fill="#FFF9EB" sketch:type="MSShapeGroup" x="153" y="136" width="113" height="24"></rect>
|
||||
<rect id="Rectangle-9" stroke="#E8C48E" stroke-width="4" fill="#FFF9EB" sketch:type="MSShapeGroup" x="153" y="2" width="113" height="24"></rect>
|
||||
<rect id="Rectangle-8" stroke="#E8C48E" stroke-width="4" fill="#FFF9EB" sketch:type="MSShapeGroup" x="119" y="68" width="194" height="24"></rect>
|
||||
<text id="<DIV>" sketch:type="MSTextLayer" font-family="Open Sans" font-size="14" font-weight="526" sketch:alignment="middle" fill="#8A704D">
|
||||
<tspan x="189.051859" y="288"><DIV></tspan>
|
||||
</text>
|
||||
|
|
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 9.9 KiB |
|
@ -260,12 +260,13 @@ alert( articles.length ); // 2, найдёт оба элемента
|
|||
|
||||
## closest
|
||||
|
||||
Метод `elem.closest(css)` ищет ближайшего предка, подходящего под CSS-селектор `css`.
|
||||
Метод `elem.closest(css)` ищет ближайший элемент выше по иерархии DOM, подходящий под CSS-селектор `css`. Сам элемент тоже включается в поиск.
|
||||
|
||||
Иначе говоря, метод `closest` бежит от текущего элемента вверх по цепочке родителей и проверяет, подходит ли каждый элемент под CSS-селектор. Если подходит -- останавливается и возвращает его.
|
||||
|
||||
Он самый новый из методов, рассмотренных в этой главе, поэтому не все браузеры его поддерживают. Это, конечно, легко поправимо, как мы увидим позже в главе [](/dom-polyfill).
|
||||
|
||||
Пример использования:
|
||||
|
||||
Пример использования (браузер должен поддерживать `closest`):
|
||||
|
||||
```html
|
||||
<!--+ run -->
|
||||
|
@ -282,10 +283,15 @@ alert( articles.length ); // 2, найдёт оба элемента
|
|||
<script>
|
||||
var numberSpan = document.querySelector('.num');
|
||||
|
||||
// браузер должен поддерживать этот метод
|
||||
// ближайший элемент сверху подходящий под селектор li
|
||||
alert( numberSpan.closest('li').className ) // subchapter
|
||||
|
||||
// ближайший элемент сверху подходящий под селектор .chapter
|
||||
alert( numberSpan.closest('.chapter').tagName ) // LI
|
||||
|
||||
// ближайший элемент сверху, подходящий под селектор span
|
||||
// это сам numberSpan, так как поиск включает в себя сам элемент
|
||||
alert( numberSpan.closest('span') === numberSpan ) // true
|
||||
</script>
|
||||
```
|
||||
|
||||
|
|
|
@ -407,7 +407,7 @@ chatDiv.innerHTML += "Как дела?";
|
|||
|
||||
**Иными словами, `elem.textContent` возвращает конкатенацию всех текстовых узлов внутри `elem`.**
|
||||
|
||||
Не сказать, чтобы эта информация была часто востребована.
|
||||
Не сказать, чтобы эта информация была часто востребована.
|
||||
|
||||
**Гораздо полезнее возможность записать текст в элемент, причём именно как текст!**
|
||||
|
||||
|
|
|
@ -372,7 +372,7 @@ div.classList.add('order-state-canceled');
|
|||
|
||||
Проще говоря, значение атрибута -- произвольная строка, значение класса -- это "есть" или "нет", поэтому естественно, что атрибуты "мощнее" и бывают удобнее классов как в JS так и в CSS.
|
||||
|
||||
## Свойство dataSet, data-атрибуты
|
||||
## Свойство dataset, data-атрибуты
|
||||
|
||||
С помощью нестандартных атрибутов можно привязать к элементу данные, которые будут доступны в JavaScript.
|
||||
|
||||
|
|