renovations
This commit is contained in:
parent
76e6717d83
commit
c254fc773d
3 changed files with 157 additions and 12 deletions
|
@ -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-узлов есть и другие свойства, зависящие от типа, например:
|
||||||
|
|
|
@ -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) -- табличка совместимости внизу.
|
||||||
|
|
||||||
|
|
|
@ -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 -- ознакомьтесь с их проблемами. Ничего критичного, но они, всё же, есть.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue