Skip to content

Commit c254fc7

Browse files
committed
renovations
1 parent 76e6717 commit c254fc7

File tree

3 files changed

+157
-12
lines changed

3 files changed

+157
-12
lines changed

2-ui/1-document/7-basic-dom-node-properties/article.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,33 @@ chatDiv.innerHTML += "Как дела?";
442442
Впрочем, при записи значения `innerText` работает так же, как и `textContent`.
443443
[/warn]
444444

445+
## Свойство hidden
446+
447+
Как правило, видим или невидим узел, определяется через CSS, свойствами `display` или `visibility`.
448+
449+
В стандарте HTML5 предусмотрен специальный атрибут (он же свойство) для этого: `hidden`.
450+
451+
Его поддерживают все современные браузеры, кроме старых IE.
452+
453+
В примере ниже второй и третий `<div>` скрыты:
454+
455+
```html
456+
<!--+ run height="80" -->
457+
<div>Текст</div>
458+
<div hidden>С атрибутом hidden</div>
459+
<div>Со свойством hidden</div>
460+
461+
<script>
462+
var lastDiv = document.body.children[2];
463+
lastDiv.hidden = true;
464+
</script>
465+
```
466+
467+
Технически, атрибут `hidden` работает так же, как `style="display:none"`. Но его проще поставить через JavaScript (меньше букв), и могут быть преимущества для скринридеров и прочих нестандартных браузеров.
468+
469+
Для старых IE тоже можно сделать, чтобы свойство поддерживалось, мы ещё вернёмся к этому далее в учебнике.
470+
471+
445472
## Исследование элементов
446473

447474
У DOM-узлов есть и другие свойства, зависящие от типа, например:

2-ui/1-document/8-dom-polyfill/article.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,10 @@ alert( document.body.lowerTag ); // body
163163
В IE6,7 геттеры/сеттеры совсем не работают. Когда-то для них использовалась особая "IE-магия" при помощи `.htc`-файлов, которые [более не поддерживаются](http://msdn.microsoft.com/en-us/library/ie/hh801216.aspx). Если нужно поддерживать и эти версии, то рекомендуется воспользоваться фреймворками. К счастью, для большинства проектов эти браузеры уже стали историей.
164164
[/warn]
165165

166-
## А есть ли поддержка?
167166

168-
А нужен ли вообще полифилл? Какие браузеры поддерживают свойство или метод?
167+
## Какова поддержка свойства?
168+
169+
А нужен ли вообще полифилл? Какие браузеры поддерживают интересное нам свойство или метод?
169170

170171
Зачастую такая информация есть в справочнике MDN, например для метода `remove()`: [](https://developer.mozilla.org/en-US/docs/Web/API/ChildNode.remove) -- табличка совместимости внизу.
171172

2-ui/1-document/9-attributes-and-custom-properties/article.md

Lines changed: 127 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -111,19 +111,19 @@ document.body.sayHi(); // BODY, выполнилась с правильным t
111111
<li>Коллекция `attributes` содержит все атрибуты в виде объектов со свойствами `name` и `value`.</li>
112112
</ol>
113113

114-
## Зачем полезны атрибуты?
114+
## Когда полезен доступ к атрибутам?
115115

116116
Когда браузер читает HTML и создаёт DOM-модель, то он создаёт свойства для всех *стандартных* атрибутов.
117117

118118
Например, свойства тега `'A'` описаны в спецификации DOM: <a href="http://www.w3.org/TR/REC-DOM-Level-1/level-one-html.html#ID-48250443">HTMLAnchorElement</a>.
119119

120120
Например, у него есть свойство `"href"`. Кроме того, он имеет `"id"` и другие свойства, общие для всех элементов, которые описаны в спецификации в <a href="http://www.w3.org/TR/REC-DOM-Level-1/level-one-html.html#ID-58190037">HTMLElement</a>.
121121

122-
В большинстве случаев стандартные свойства DOM синхронизируются с атрибутами. Но не всегда такая синхронизация происходит 1-в-1, поэтому иногда нам нужно значение именно из HTML.
122+
Все стандартные свойства DOM синхронизируются с атрибутами, однако не всегда такая синхронизация происходит 1-в-1, поэтому иногда нам нужно значение именно из HTML, то есть атрибут.
123123

124-
В этом случае мы берём его через атрибут.
124+
Рассмотрим несколько примеров.
125125

126-
### Значения могут быть разными: href
126+
### Ссылка "как есть" из атрибута href
127127

128128
Синхронизация не гарантирует одинакового значения в атрибуте и свойстве.
129129

@@ -173,11 +173,11 @@ document.body.sayHi(); // BODY, выполнилась с правильным t
173173
```
174174
[/smart]
175175

176-
### Свойство не всегда обновляет атрибут: value
176+
### Исходное значение value
177177

178178
Изменение некоторых свойств обновляет атрибут. Но это скорее исключение, чем правило.
179179

180-
**Обычно синхронизация -- односторонняя: свойство зависит от атрибута.**
180+
**Чаще синхронизация -- односторонняя: свойство зависит от атрибута, но не наоборот.**
181181

182182
Например, при изменении свойства `input.value` атрибут `input.getAttribute('value')` не меняется:
183183

@@ -195,7 +195,7 @@ document.body.sayHi(); // BODY, выполнилась с правильным t
195195
</body>
196196
```
197197

198-
То есть, изменение свойства на атрибут не влияет, он остаётся таким же.
198+
То есть, изменение DOM-свойства `value` на атрибут не влияет, он остаётся таким же.
199199

200200
А вот изменение атрибута обновляет свойство:
201201

@@ -219,7 +219,7 @@ document.body.sayHi(); // BODY, выполнилась с правильным t
219219

220220
Например, можно взять изначальное значение из атрибута и сравнить со свойством, чтобы узнать, изменилось ли значение. А при необходимости и перезаписать свойство атрибутом, отменив изменения.
221221

222-
### Атрибут class -- className
222+
## Классы в виде строки: className
223223

224224
Атрибуту `"class"` соответствует свойство `className`.
225225

@@ -242,7 +242,7 @@ document.body.sayHi(); // BODY, выполнилась с правильным t
242242

243243
Кстати, есть и другие атрибуты, которые называются иначе, чем свойство. Например, атрибуту `for` (`<label for="...">`) соответствует свойство с названием `htmlFor`.
244244

245-
### Атрибут class -- объект classList
245+
## Классы в виде объекта: classList
246246

247247
Атрибут `class` -- уникален. Ему соответствует аж целых два свойства!
248248

@@ -283,6 +283,7 @@ document.body.sayHi(); // BODY, выполнилась с правильным t
283283
</body>
284284
```
285285

286+
286287
## Нестандартные атрибуты
287288

288289
У каждого элемента есть некоторый набор стандартных свойств, например для `<a>` это будут `href`, `name`, `title`, а для `<img>` это будут `src`, `alt`, и так далее.
@@ -320,9 +321,60 @@ document.body.sayHi(); // BODY, выполнилась с правильным t
320321
</script>
321322
```
322323

324+
Нестандартные атрибуты иногда используют для CSS.
325+
326+
В примере ниже для показа "состояния заказа" используется атрибут `order-state`:
327+
328+
```html
329+
<!--+ run -->
330+
<style>
331+
.order[order-state="new"] {
332+
color: green;
333+
}
334+
.order[order-state="pending"] {
335+
color: blue;
336+
}
337+
.order[order-state="canceled"] {
338+
color: red;
339+
}
340+
</style>
341+
342+
<div class="order" order-state="new">
343+
Новый заказ.
344+
</div>
345+
346+
<div class="order" order-state="pending">
347+
Ожидающий заказ.
348+
</div>
349+
350+
<div class="order" order-state="canceled">
351+
Заказ отменён.
352+
</div>
353+
```
354+
355+
Почему именно атрибут? Разве нельзя было сделать классы `.order-state-new`, `.order-state-pending`, `order-state-canceled`?
356+
357+
Конечно можно, но манипулировать атрибутом из JavaScript гораздо проще.
358+
359+
Например, если нужно отменить заказ, неважно в каком он состоянии сейчас -- это сделает код:
360+
```js
361+
div.setAttribute('order-state', 'canceled');
362+
```
363+
364+
Для классов -- нужно знать, какой класс у заказа сейчас. И тогда мы можем снять старый класс, и поставить новый:
365+
366+
```js
367+
div.classList.remove('order-state-new');
368+
div.classList.add('order-state-canceled');
369+
```
370+
371+
...То есть, требуется больше исходной информации и надо написать больше букв. Это менее удобно.
372+
373+
Проще говоря, значение атрибута -- произвольная строка, значение класса -- это "есть" или "нет", поэтому естественно, что атрибуты "мощнее" и бывают удобнее классов как в JS так и в CSS.
374+
323375
## Свойство dataSet, data-атрибуты
324376

325-
Нестандартные атрибуты никак не влияют на внешний вид элемента, но с их помощью можно привязать к элементу данные, которые будут доступны в JavaScript.
377+
С помощью нестандартных атрибутов можно привязать к элементу данные, которые будут доступны в JavaScript.
326378

327379
Как правило, это делается при помощи атрибутов с названиями, начинающимися на `data-`, например:
328380

@@ -356,6 +408,71 @@ document.body.sayHi(); // BODY, выполнилась с правильным t
356408

357409
Обратим внимание -- название `data-user-location` трансформировалось в `dataset.userLocation`. Дефис превращается в большую букву.
358410

411+
## Полифилл для атрибута hidden
412+
413+
Для старых браузеров современные атрибуты иногда нуждаются в полифилле. Как правило, такой полифилл включает в себя не только JavaScript, но и CSS.
414+
415+
Например, свойство/атрибут hidden не поддерживается в IE11.
416+
417+
Этот атрибут должен прятать элемент, действие весьма простое, для его поддержки в HTML достаточно такого CSS:
418+
419+
```html
420+
<!--+ run height="80" -->
421+
<style>
422+
*!*
423+
[hidden] { display: none }
424+
*/!*
425+
</style>
426+
427+
<div>Текст</div>
428+
<div hidden>С атрибутом hidden</div>
429+
<div id="last">Со свойством hidden</div>
430+
431+
<script>
432+
last.hidden = true;
433+
</script>
434+
```
435+
436+
Если запустить в IE11- пример выше, то `<div hidden>` будет скрыт, а вот последний `div`, которому поставили свойство `hidden` в JavaScript -- по-прежнему виден.
437+
438+
Это потому что CSS "не видит" присвоенное свойство, нужно синхронизировать его в атрибут.
439+
440+
Вот так -- уже работает:
441+
442+
443+
```html
444+
<!--+ run height="80" -->
445+
<style>
446+
*!*
447+
[hidden] { display: none }
448+
*/!*
449+
</style>
450+
451+
<script>
452+
*!*
453+
if (document.documentElement.hidden === undefined) {
454+
Object.defineProperty(Element.prototype, "hidden", {
455+
set: function(value) {
456+
this.setAttribute('hidden', value);
457+
},
458+
get: function() {
459+
return this.getAttribute('hidden');
460+
}
461+
});
462+
}
463+
*/!*
464+
</script>
465+
466+
<div>Текст</div>
467+
<div hidden>С атрибутом hidden</div>
468+
<div id="last">Со свойством hidden</div>
469+
470+
<script>
471+
last.hidden = true;
472+
</script>
473+
```
474+
475+
359476
## "Особенности" IE8-
360477
361478
Если вам нужна поддержка этих версий IE -- ознакомьтесь с их проблемами. Ничего критичного, но они, всё же, есть.

0 commit comments

Comments
 (0)