
- •Окружение: dom,boMиJs
- •Bom-объекты:navigator,screen,location,frames navigator: платформа и браузер
- •Location
- •Методы и свойства Location
- •Методы объекта Location
- •History
- •Дерево dom
- •Пример dom
- •Ещё узлы
- •Возможности, которые дает dom
- •Работа с dom из консоли Доступ к элементу
- •Elements - Консоль
- •Навигация в dom, свойства-ссылки Корень: documentElement и body
- •Дочерние элементы
- •ChildNodes
- •Ссылки вверх и вниз
- •FirstChild и lastChild
- •Свойства узлов: тип, тег, содержимое и другие
- •Тип: nodeType
- •Тег: nodeName и tagName
- •Какая разница между tagName и nodeName ?
- •InnerHtml: содержимое элемента
- •Тонкости innerHtml
- •OuterHtml: html узла целиком
- •NodeValue/data: содержимое текстового узла
- •Другие свойства
- •InnerHtml
- •Атрибуты и "свои" свойства
- •«Свои» свойства
- •Атрибуты
Тег: nodeName и tagName
Существует целых два свойства: nodeName и tagName, которые содержат название(тег) элемента узла.
Название HTML-тега всегда находится в верхнем регистре.
Например, для document.body:
<!DOCTYPE html>
<html>
<head>
<title> </title>
</head>
<body>
<script>
alert( document.body.nodeName ); // BODY
alert( document.body.tagName ); // BODY
</script>
</body>
</html>
Когда nodeName не в верхнем регистре?
У браузера есть два режима обработки документа: HTML и XML-режим. Обычно используется режим HTML, XML-режим включается, когда браузер получает XML-документ через XMLHttpRequest(технология AJAX) или при наличии заголовка Content-Type: application/xml+xhtml.
В XML-режиме сохраняется регистр и nodeName может выдать «body» или даже «bOdY» — в точности как указано в документе.
Какая разница между tagName и nodeName ?
Разница отражена в названиях свойств, но неочевидна.
Свойство nodeName определено для многих типов DOM-узлов.
Свойство tagName — есть только у элементов (в IE<9 также у комментариев, это ошибка в браузере).
Иначе говоря, при помощи tagName мы можем работать только с элементами, а nodeName может что-то сказать и о других типах узлов.
Например
<body><!-- комментарий -->
<script>
// для комментария
alert(document.body.firstChild.nodeName); // #comment
alert(document.body.firstChild.tagName); // undefined (в IE<9 воскл. знак "!")
// для документа
alert(document.nodeName); // #document, т.к. корень DOM -- не элемент
alert(document.tagName); // undefined
</script>
</body>
При работе только с узлами элементов имеет смысл использовать tagName — так короче
Задание
Напишите функцию getNextElement(elem), которая возвращает следующий за elem узел-элемент (игнорирует остальные узлы).
<div>Первый</div>
<!-- комментарий... -->
<p>Второй</p>
<script>
function getNextElement(elem) { /* ваш код */ }
alert(getNextElement(document.body.children[0]).tagName); // P
alert(getNextElement(document.body.lastChild)); // null
</script>
P.S. Функция должна работать максимально эффективно и учитывать возможности современных браузеров.
Ответ
Поддержка свойства nextElementSibling в браузере либо есть, либо её нет. Зачем проверять её для каждого элемента? Можно сделать это один раз и запомнить результат. А можно поступить ещё лучше — определить функцию по-разному, в зависимости от того, поддерживается это свойство или нет.
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div>Первый</div>
<!-- комментарий... -->
<p>Второй</p>
<script>
var getNextElement =
document.documentElement.nextElementSibling !== undefined ?
function(elem) {
return elem.nextElementSibling;
}
:
function(elem) {
var current = elem.nextSibling;
while(current && current.nodeType != 1) {
current = current.nextSibling;
}
return current;
};
alert(getNextElement(document.body.children[0]).tagName); // "P"
alert(getNextElement(document.body.lastChild)); // null
</script>
</body>
</html>
InnerHtml: содержимое элемента
Свойство innerHTML описано в спецификации HTML 5 — embedded content.
Оно позволяет получить HTML-содержимое узла в виде строки. В innerHTML можно и читать и писать.
Пример выведет на экран все содержимое document.body, а затем заменит его на другое
<body>
<p>Параграф</p>
<div>Div</div>
<script>
alert( document.body.innerHTML ); // читаем текущее содержимое
document.body.innerHTML = 'Новый BODY!'; // заменяем содержимое
</script>
</body>
При чтении innerHTML HTML-код всегда будет валиден. При записи — можно записать что угодно, браузер поправит некорректный HTML-код:
<body>
<script>
document.body.innerHTML = '<b>тест'; // незакрытый тег
alert(document.body.innerHTML); // <b>тест</b> (исправлено)
</script>
</body>