renovations

This commit is contained in:
Ilya Kantor 2015-02-03 19:31:48 +03:00
parent 76e6717d83
commit c254fc773d
3 changed files with 157 additions and 12 deletions

View file

@ -442,6 +442,33 @@ chatDiv.innerHTML += "Как дела?";
Впрочем, при записи значения `innerText` работает так же, как и `textContent`. Впрочем, при записи значения `innerText` работает так же, как и `textContent`.
[/warn] [/warn]
## Свойство hidden
Как правило, видим или невидим узел, определяется через CSS, свойствами `display` или `visibility`.
В стандарте HTML5 предусмотрен специальный атрибут (он же свойство) для этого: `hidden`.
Его поддерживают все современные браузеры, кроме старых IE.
В примере ниже второй и третий `<div>` скрыты:
```html
<!--+ run height="80" -->
<div>Текст</div>
<div hidden>С атрибутом hidden</div>
<div>Со свойством hidden</div>
<script>
var lastDiv = document.body.children[2];
lastDiv.hidden = true;
</script>
```
Технически, атрибут `hidden` работает так же, как `style="display:none"`. Но его проще поставить через JavaScript (меньше букв), и могут быть преимущества для скринридеров и прочих нестандартных браузеров.
Для старых IE тоже можно сделать, чтобы свойство поддерживалось, мы ещё вернёмся к этому далее в учебнике.
## Исследование элементов ## Исследование элементов
У DOM-узлов есть и другие свойства, зависящие от типа, например: У DOM-узлов есть и другие свойства, зависящие от типа, например:

View file

@ -163,9 +163,10 @@ alert( document.body.lowerTag ); // body
В IE6,7 геттеры/сеттеры совсем не работают. Когда-то для них использовалась особая "IE-магия" при помощи `.htc`-файлов, которые [более не поддерживаются](http://msdn.microsoft.com/en-us/library/ie/hh801216.aspx). Если нужно поддерживать и эти версии, то рекомендуется воспользоваться фреймворками. К счастью, для большинства проектов эти браузеры уже стали историей. В IE6,7 геттеры/сеттеры совсем не работают. Когда-то для них использовалась особая "IE-магия" при помощи `.htc`-файлов, которые [более не поддерживаются](http://msdn.microsoft.com/en-us/library/ie/hh801216.aspx). Если нужно поддерживать и эти версии, то рекомендуется воспользоваться фреймворками. К счастью, для большинства проектов эти браузеры уже стали историей.
[/warn] [/warn]
## А есть ли поддержка?
А нужен ли вообще полифилл? Какие браузеры поддерживают свойство или метод? ## Какова поддержка свойства?
А нужен ли вообще полифилл? Какие браузеры поддерживают интересное нам свойство или метод?
Зачастую такая информация есть в справочнике MDN, например для метода `remove()`: [](https://developer.mozilla.org/en-US/docs/Web/API/ChildNode.remove) -- табличка совместимости внизу. Зачастую такая информация есть в справочнике MDN, например для метода `remove()`: [](https://developer.mozilla.org/en-US/docs/Web/API/ChildNode.remove) -- табличка совместимости внизу.

View file

@ -111,7 +111,7 @@ document.body.sayHi(); // BODY, выполнилась с правильным t
<li>Коллекция `attributes` содержит все атрибуты в виде объектов со свойствами `name` и `value`.</li> <li>Коллекция `attributes` содержит все атрибуты в виде объектов со свойствами `name` и `value`.</li>
</ol> </ol>
## Зачем полезны атрибуты? ## Когда полезен доступ к атрибутам?
Когда браузер читает HTML и создаёт DOM-модель, то он создаёт свойства для всех *стандартных* атрибутов. Когда браузер читает HTML и создаёт DOM-модель, то он создаёт свойства для всех *стандартных* атрибутов.
@ -119,11 +119,11 @@ document.body.sayHi(); // BODY, выполнилась с правильным t
Например, у него есть свойство `"href"`. Кроме того, он имеет `"id"` и другие свойства, общие для всех элементов, которые описаны в спецификации в <a href="http://www.w3.org/TR/REC-DOM-Level-1/level-one-html.html#ID-58190037">HTMLElement</a>. Например, у него есть свойство `"href"`. Кроме того, он имеет `"id"` и другие свойства, общие для всех элементов, которые описаны в спецификации в <a href="http://www.w3.org/TR/REC-DOM-Level-1/level-one-html.html#ID-58190037">HTMLElement</a>.
В большинстве случаев стандартные свойства DOM синхронизируются с атрибутами. Но не всегда такая синхронизация происходит 1-в-1, поэтому иногда нам нужно значение именно из HTML. Все стандартные свойства DOM синхронизируются с атрибутами, однако не всегда такая синхронизация происходит 1-в-1, поэтому иногда нам нужно значение именно из HTML, то есть атрибут.
В этом случае мы берём его через атрибут. Рассмотрим несколько примеров.
### Значения могут быть разными: href ### Ссылка "как есть" из атрибута href
Синхронизация не гарантирует одинакового значения в атрибуте и свойстве. Синхронизация не гарантирует одинакового значения в атрибуте и свойстве.
@ -173,11 +173,11 @@ document.body.sayHi(); // BODY, выполнилась с правильным t
``` ```
[/smart] [/smart]
### Свойство не всегда обновляет атрибут: value ### Исходное значение value
Изменение некоторых свойств обновляет атрибут. Но это скорее исключение, чем правило. Изменение некоторых свойств обновляет атрибут. Но это скорее исключение, чем правило.
**Обычно синхронизация -- односторонняя: свойство зависит от атрибута.** **Чаще синхронизация -- односторонняя: свойство зависит от атрибута, но не наоборот.**
Например, при изменении свойства `input.value` атрибут `input.getAttribute('value')` не меняется: Например, при изменении свойства `input.value` атрибут `input.getAttribute('value')` не меняется:
@ -195,7 +195,7 @@ document.body.sayHi(); // BODY, выполнилась с правильным t
</body> </body>
``` ```
То есть, изменение свойства на атрибут не влияет, он остаётся таким же. То есть, изменение DOM-свойства `value` на атрибут не влияет, он остаётся таким же.
А вот изменение атрибута обновляет свойство: А вот изменение атрибута обновляет свойство:
@ -219,7 +219,7 @@ document.body.sayHi(); // BODY, выполнилась с правильным t
Например, можно взять изначальное значение из атрибута и сравнить со свойством, чтобы узнать, изменилось ли значение. А при необходимости и перезаписать свойство атрибутом, отменив изменения. Например, можно взять изначальное значение из атрибута и сравнить со свойством, чтобы узнать, изменилось ли значение. А при необходимости и перезаписать свойство атрибутом, отменив изменения.
### Атрибут class -- className ## Классы в виде строки: className
Атрибуту `"class"` соответствует свойство `className`. Атрибуту `"class"` соответствует свойство `className`.
@ -242,7 +242,7 @@ document.body.sayHi(); // BODY, выполнилась с правильным t
Кстати, есть и другие атрибуты, которые называются иначе, чем свойство. Например, атрибуту `for` (`<label for="...">`) соответствует свойство с названием `htmlFor`. Кстати, есть и другие атрибуты, которые называются иначе, чем свойство. Например, атрибуту `for` (`<label for="...">`) соответствует свойство с названием `htmlFor`.
### Атрибут class -- объект classList ## Классы в виде объекта: classList
Атрибут `class` -- уникален. Ему соответствует аж целых два свойства! Атрибут `class` -- уникален. Ему соответствует аж целых два свойства!
@ -283,6 +283,7 @@ document.body.sayHi(); // BODY, выполнилась с правильным t
</body> </body>
``` ```
## Нестандартные атрибуты ## Нестандартные атрибуты
У каждого элемента есть некоторый набор стандартных свойств, например для `<a>` это будут `href`, `name`, `title`, а для `<img>` это будут `src`, `alt`, и так далее. У каждого элемента есть некоторый набор стандартных свойств, например для `<a>` это будут `href`, `name`, `title`, а для `<img>` это будут `src`, `alt`, и так далее.
@ -320,9 +321,60 @@ document.body.sayHi(); // BODY, выполнилась с правильным t
</script> </script>
``` ```
Нестандартные атрибуты иногда используют для CSS.
В примере ниже для показа "состояния заказа" используется атрибут `order-state`:
```html
<!--+ run -->
<style>
.order[order-state="new"] {
color: green;
}
.order[order-state="pending"] {
color: blue;
}
.order[order-state="canceled"] {
color: red;
}
</style>
<div class="order" order-state="new">
Новый заказ.
</div>
<div class="order" order-state="pending">
Ожидающий заказ.
</div>
<div class="order" order-state="canceled">
Заказ отменён.
</div>
```
Почему именно атрибут? Разве нельзя было сделать классы `.order-state-new`, `.order-state-pending`, `order-state-canceled`?
Конечно можно, но манипулировать атрибутом из JavaScript гораздо проще.
Например, если нужно отменить заказ, неважно в каком он состоянии сейчас -- это сделает код:
```js
div.setAttribute('order-state', 'canceled');
```
Для классов -- нужно знать, какой класс у заказа сейчас. И тогда мы можем снять старый класс, и поставить новый:
```js
div.classList.remove('order-state-new');
div.classList.add('order-state-canceled');
```
...То есть, требуется больше исходной информации и надо написать больше букв. Это менее удобно.
Проще говоря, значение атрибута -- произвольная строка, значение класса -- это "есть" или "нет", поэтому естественно, что атрибуты "мощнее" и бывают удобнее классов как в JS так и в CSS.
## Свойство dataSet, data-атрибуты ## Свойство dataSet, data-атрибуты
Нестандартные атрибуты никак не влияют на внешний вид элемента, но с их помощью можно привязать к элементу данные, которые будут доступны в JavaScript. С помощью нестандартных атрибутов можно привязать к элементу данные, которые будут доступны в JavaScript.
Как правило, это делается при помощи атрибутов с названиями, начинающимися на `data-`, например: Как правило, это делается при помощи атрибутов с названиями, начинающимися на `data-`, например:
@ -356,6 +408,71 @@ document.body.sayHi(); // BODY, выполнилась с правильным t
Обратим внимание -- название `data-user-location` трансформировалось в `dataset.userLocation`. Дефис превращается в большую букву. Обратим внимание -- название `data-user-location` трансформировалось в `dataset.userLocation`. Дефис превращается в большую букву.
## Полифилл для атрибута hidden
Для старых браузеров современные атрибуты иногда нуждаются в полифилле. Как правило, такой полифилл включает в себя не только JavaScript, но и CSS.
Например, свойство/атрибут hidden не поддерживается в IE11.
Этот атрибут должен прятать элемент, действие весьма простое, для его поддержки в HTML достаточно такого CSS:
```html
<!--+ run height="80" -->
<style>
*!*
[hidden] { display: none }
*/!*
</style>
<div>Текст</div>
<div hidden>С атрибутом hidden</div>
<div id="last">Со свойством hidden</div>
<script>
last.hidden = true;
</script>
```
Если запустить в IE11- пример выше, то `<div hidden>` будет скрыт, а вот последний `div`, которому поставили свойство `hidden` в JavaScript -- по-прежнему виден.
Это потому что CSS "не видит" присвоенное свойство, нужно синхронизировать его в атрибут.
Вот так -- уже работает:
```html
<!--+ run height="80" -->
<style>
*!*
[hidden] { display: none }
*/!*
</style>
<script>
*!*
if (document.documentElement.hidden === undefined) {
Object.defineProperty(Element.prototype, "hidden", {
set: function(value) {
this.setAttribute('hidden', value);
},
get: function() {
return this.getAttribute('hidden');
}
});
}
*/!*
</script>
<div>Текст</div>
<div hidden>С атрибутом hidden</div>
<div id="last">Со свойством hidden</div>
<script>
last.hidden = true;
</script>
```
## "Особенности" IE8- ## "Особенности" IE8-
Если вам нужна поддержка этих версий IE -- ознакомьтесь с их проблемами. Ничего критичного, но они, всё же, есть. Если вам нужна поддержка этих версий IE -- ознакомьтесь с их проблемами. Ничего критичного, но они, всё же, есть.