You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Впрочем, при записи значения `innerText` работает так же, как и `textContent`.
443
443
[/warn]
444
444
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
+
<divhidden>С атрибутом 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
+
445
472
## Исследование элементов
446
473
447
474
У DOM-узлов есть и другие свойства, зависящие от типа, например:
Copy file name to clipboardExpand all lines: 2-ui/1-document/8-dom-polyfill/article.md
+3-2Lines changed: 3 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -163,9 +163,10 @@ alert( document.body.lowerTag ); // body
163
163
В IE6,7 геттеры/сеттеры совсем не работают. Когда-то для них использовалась особая "IE-магия" при помощи `.htc`-файлов, которые [более не поддерживаются](http://msdn.microsoft.com/en-us/library/ie/hh801216.aspx). Если нужно поддерживать и эти версии, то рекомендуется воспользоваться фреймворками. К счастью, для большинства проектов эти браузеры уже стали историей.
164
164
[/warn]
165
165
166
-
## А есть ли поддержка?
167
166
168
-
А нужен ли вообще полифилл? Какие браузеры поддерживают свойство или метод?
167
+
## Какова поддержка свойства?
168
+
169
+
А нужен ли вообще полифилл? Какие браузеры поддерживают интересное нам свойство или метод?
169
170
170
171
Зачастую такая информация есть в справочнике MDN, например для метода `remove()`: [](https://developer.mozilla.org/en-US/docs/Web/API/ChildNode.remove) -- табличка совместимости внизу.
@@ -111,19 +111,19 @@ document.body.sayHi(); // BODY, выполнилась с правильным t
111
111
<li>Коллекция `attributes` содержит все атрибуты в виде объектов со свойствами `name` и `value`.</li>
112
112
</ol>
113
113
114
-
## Зачем полезны атрибуты?
114
+
## Когда полезен доступ к атрибутам?
115
115
116
116
Когда браузер читает HTML и создаёт DOM-модель, то он создаёт свойства для всех *стандартных* атрибутов.
117
117
118
118
Например, свойства тега `'A'` описаны в спецификации DOM: <ahref="http://www.w3.org/TR/REC-DOM-Level-1/level-one-html.html#ID-48250443">HTMLAnchorElement</a>.
119
119
120
120
Например, у него есть свойство `"href"`. Кроме того, он имеет `"id"` и другие свойства, общие для всех элементов, которые описаны в спецификации в <ahref="http://www.w3.org/TR/REC-DOM-Level-1/level-one-html.html#ID-58190037">HTMLElement</a>.
121
121
122
-
В большинстве случаев стандартные свойства DOM синхронизируются с атрибутами. Но не всегда такая синхронизация происходит 1-в-1, поэтому иногда нам нужно значение именно из HTML.
122
+
Все стандартные свойства DOM синхронизируются с атрибутами, однако не всегда такая синхронизация происходит 1-в-1, поэтому иногда нам нужно значение именно из HTML, то есть атрибут.
123
123
124
-
В этом случае мы берём его через атрибут.
124
+
Рассмотрим несколько примеров.
125
125
126
-
### Значения могут быть разными: href
126
+
### Ссылка "как есть" из атрибута href
127
127
128
128
Синхронизация не гарантирует одинакового значения в атрибуте и свойстве.
129
129
@@ -173,11 +173,11 @@ document.body.sayHi(); // BODY, выполнилась с правильным t
173
173
```
174
174
[/smart]
175
175
176
-
### Свойство не всегда обновляет атрибут: value
176
+
### Исходное значение value
177
177
178
178
Изменение некоторых свойств обновляет атрибут. Но это скорее исключение, чем правило.
179
179
180
-
**Обычно синхронизация -- односторонняя: свойство зависит от атрибута.**
180
+
**Чаще синхронизация -- односторонняя: свойство зависит от атрибута, но не наоборот.**
181
181
182
182
Например, при изменении свойства `input.value` атрибут `input.getAttribute('value')` не меняется:
183
183
@@ -195,7 +195,7 @@ document.body.sayHi(); // BODY, выполнилась с правильным t
195
195
</body>
196
196
```
197
197
198
-
То есть, изменение свойства на атрибут не влияет, он остаётся таким же.
198
+
То есть, изменение DOM-свойства`value` на атрибут не влияет, он остаётся таким же.
199
199
200
200
А вот изменение атрибута обновляет свойство:
201
201
@@ -219,7 +219,7 @@ document.body.sayHi(); // BODY, выполнилась с правильным t
219
219
220
220
Например, можно взять изначальное значение из атрибута и сравнить со свойством, чтобы узнать, изменилось ли значение. А при необходимости и перезаписать свойство атрибутом, отменив изменения.
221
221
222
-
### Атрибут class -- className
222
+
##Классы в виде строки: className
223
223
224
224
Атрибуту `"class"` соответствует свойство `className`.
225
225
@@ -242,7 +242,7 @@ document.body.sayHi(); // BODY, выполнилась с правильным t
242
242
243
243
Кстати, есть и другие атрибуты, которые называются иначе, чем свойство. Например, атрибуту `for` (`<label for="...">`) соответствует свойство с названием `htmlFor`.
244
244
245
-
### Атрибут class -- объект classList
245
+
##Классы в виде объекта: classList
246
246
247
247
Атрибут `class` -- уникален. Ему соответствует аж целых два свойства!
248
248
@@ -283,6 +283,7 @@ document.body.sayHi(); // BODY, выполнилась с правильным t
283
283
</body>
284
284
```
285
285
286
+
286
287
## Нестандартные атрибуты
287
288
288
289
У каждого элемента есть некоторый набор стандартных свойств, например для `<a>` это будут `href`, `name`, `title`, а для `<img>` это будут `src`, `alt`, и так далее.
@@ -320,9 +321,60 @@ document.body.sayHi(); // BODY, выполнилась с правильным t
320
321
</script>
321
322
```
322
323
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
+
<divclass="order"order-state="new">
343
+
Новый заказ.
344
+
</div>
345
+
346
+
<divclass="order"order-state="pending">
347
+
Ожидающий заказ.
348
+
</div>
349
+
350
+
<divclass="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
+
323
375
## Свойство dataSet, data-атрибуты
324
376
325
-
Нестандартные атрибуты никак не влияют на внешний вид элемента, но с их помощью можно привязать к элементу данные, которые будут доступны в JavaScript.
377
+
С помощью нестандартных атрибутов можно привязать к элементу данные, которые будут доступны в JavaScript.
326
378
327
379
Как правило, это делается при помощи атрибутов с названиями, начинающимися на `data-`, например:
328
380
@@ -356,6 +408,71 @@ document.body.sayHi(); // BODY, выполнилась с правильным t
356
408
357
409
Обратим внимание -- название `data-user-location` трансформировалось в `dataset.userLocation`. Дефис превращается в большую букву.
358
410
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) {
0 commit comments