Можно обрабатывать вложенные узлы DOM либо как массив (childNodes), либо как список (firstChild, nextSibling). Для доступа только к элементам (без текстовых узлов) используется коллекция children вместо childNodes.
Кроме специальных элементов ``head`` и ``body`` можно получить коллекцию всех ссылок на странице как ``document.links``, картинок как ``document.images`` и т.д.
В зависимости от типа узлы имеют разные наборы [свойств](https://learn.javascript.ru/basic-dom-node-properties):
``nodeName, nodeType`` (у всех узлов),
``tagName, innerHTML, innerText`` (только у HTML-элементов, последние можно изменять).
Скрипты подключаются с помощью тега ``<script>``. Они выполняются сразу после загрузки, поэтому ``document.body`` может быть null, если он включен в ``<head>``.
Если вы используете для отладочной печати console.log в браузере результат можно увидеть с помощью пункта меню "Инструменты разработчика".
*Задание 8*: найдите результаты выполнения этого скрипта.
*Задание 9*: измените текст у всех элементов ``<p>`` на ``Привет!`` с помощью скрипта.
У HTML-элементов могут быть указаны [атрибуты](https://learn.javascript.ru/dom-attributes-and-properties). Некоторые из них можно получать и изменять через специальные свойства элемента, остальные - через методы ``getAttribute(имя_атрибута)`` и ``setAttribute(имя_атрибута, новое_значение)``.
Например, атрибут ``class`` в JavaScript будет свойством ``className``, атрибут ``id`` - свойством ``id``, атрибуты с именем, начинающимся на ``data-``, - в коллекцию-объект под именем ``dataset``.
В свойстве ``style`` содержатся набор свойств отображения элемнта на странице, установленный в соответствии с таблицами CSS и аттрибута ``style``.
Атрибут ``id`` играет важную роль при взаимодействии с JavaScript. Он должен иметь уникальным в пределах HTML-страницы, и для элементов с таким атрибутом после загрузки автоматически появляется глобальная переменная, указывающая на соответствующий HTML-элемент.
*Задание 10*: замените текст в первом ``<p>`` на этот же текст, повторенный указанное в атрибуте ``data-repeat`` количество раз, и измените цвет текста красный с помощью скрипта.
Поиск элементов
Для [поиска элементов DOM](https://learn.javascript.ru/searching-elements-dom) используются следующие методы:
* ``getElementById(имя)`` - найти элемент с id=имя (только для document);
* ``querySelectorAll(css-селектор)`` - найти всех потомков, соответствующего указанному css-селектору (для элементов и document);
* ``querySelector(css-селектор)`` - найти первого потомка, соответствующего указанному css-селектору (для элементов и document);
* ``closest(css-селектор)`` - найти первого предка, соответствующего указанному css-селектору (только для элементов)
Для самостоятельного поиска можно применить метод ``match(css-селектор)`` для проверки элемента на соответствие селектору.
```run-html
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251" />
</head>
<body>
<h1>Заголовок</h1>
<table>
<tr><td class="x"></td><td class="o"></td><td></td></tr>
<tr><td class="o"></td><td class="x"></td><td></td></tr>
<tr><td class="o"></td><td></td><td class="x"></td></tr>
</table>
</body>
<script>
let i=1; // заполняем таблицу числами от 1 до 9
for(let e of document.querySelectorAll("td"))
e.innerText=i++;
</script>
</html>
```
*Задание 11*: подставьте в ячейки таблицы с атрибутом class="x" символ X, а в ячейки таблицы с атрибутом class="o" - символ O.
Изменение документа
Изменять документ можно с помощью свойства ``innerHTML``, но не всегда это удобно.
Для удаления используется метод ``remove()``, применяемый к удаляемому узлу.
Для создания узлов используются методы:
* ``document.createElement(тег)`` - создание HTML-элемента;
* ``document.createTextNode(текст)`` - создание текстового узла.
После создания можно задать его свойства и добавить в DOM с помощью одного из методов:
* ``узел.append(узлы или строки)`` – добавление в конец списка подузлов;
* ``узел.prepend(узлы или строки)`` – добавление в начало списка подузлов;
* ``узел.before(узлы или строки)`` – добавление перед узлом;
* ``узел.after(узлы или строки)`` – добавление после узла;
* ``узел.replaceWith(узлы или строки)`` - замена узла.
Пример добавление строк и ячеек в таблицу.
```run-html
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251" />
</head>
<body>
<h1>Заголовок</h1>
<table id="mytable" data-row="3" data-col="3">
</table>
</body>
<script>
let tr=document.createElement('tr');
mytable.append(tr);
let td=document.createElement('td');
td.innerText="0";
tr.append(td);
</script>
</html>
```
*Задание 12*: создайте data-row строк c data-col ячеек в каждой строке и заполните их как таблицу умножения - в ячейке в `i`-й строке `j`-м столбце должно стоять произведение `i*j`.
Обработка событий
JavaScript позволяет обрабатывать многие [действия](https://learn.javascript.ru/introduction-browser-events) пользователя на странице и изменять страницу соответствующим образом.
Чаще всего необходимо отрабатывать щелчки мышью на элементов - событие click.
Добавить обработчик события onclick можно двумя способами:
* ``элемент.onclick=функция``;
* ``элемент.addEventListener('click', функция, опции)``, где опции можно пропустить.
Аналогично для других событий.
```run-html
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251" />
</head>
<body>
Значение 1: <input id="op1"></input><br>
Значение 2: <input id="op2"></input><br>
<p>Результат: <span id="res">?</span></p>
<button id="calc">Вычислить</button>
</body>
<script>
calc.onclick=function(){
res.innerText=op1.value*op2.value;
}
</script>
</html>
```
*Задание 13*: Переделайте решение из задания 12, чтобы количество строк и столбцов вводилось пользователем, а таблица заполнялась при нажатии на кнопку. Для очистки таблицы используйте ``mytable.innerHTML='';``.