На первую часть вопроса мне помогли ответить толковые ребята с тостера. На вторую часть вопроса, а именно
2. Зачем браузер запихивает лишние текстовые узлы между моих узлов? Зачем-то же это придумали разработчики. я отвечу сам.
Браузер расценивает любые символы (числа, буквы, пробел, перевод строки, табуляцию…), которые не лежат в элементе, как текстовый узел. В моем документе HTML ВСЕ ВЫВОДИТСЯ НА ЭКРАН (кроме служебных элементов), и, когда я ввожу символы какие-то ВНЕ служебных элементов, то браузер думает «Ага, он хочется, чтобы я их вывел. Стоп, но они же не внутри элемента, тогда выведу их, как обычный текстовый узел (у которого объектом-прототипом является объект-прототип Text)». Я раньше сталкивался с подобной ситуацией, но не понимал, почему так. Например, я пишу код:
…
<body>
Привет
<div>123</div>
…
Вот этот текст «Привет» как раз и запихнули в такой объект-узел текстовый. Поэтому «Привет» и вывелся на экран, хотя я думал «Почему он выводится, он же не в элементе?». Но помни, что текст-тексту рознь (про это написано в следующем курсе по JavaScript). У этого объекта-узла «Привет» объект-прототип Text. Если же я создаю джаваскриптом переменную-объект с использованием функции-конструктора String(), то у этого объекта объект–прототип (а значит, свойства и методы совсем другие) совсем другой – String{…}.
То есть, ВСЯ РАЗМЕТКА НЕСЛУЖЕБНОЙ ЧАСТИ МОЕГО ХТМЛ-ДОКУМЕНТА ВМЕСТЕ С СИМВОЛАМИ МЕЖДУ САМИМИ ЭЛЕМЕНТАМИ РАЗМЕТКИ (пробел, табуляция, перевод строки…) расценивается браузером как то, ЧТО Я ХОЧУ ВЫВЕСТИ НА ЭКРАН, преобразуется в объекты-узлы дерева DOM (подчеркиваю, что именно объекты-УЗЛЫ – они ВЫВОДЯТСЯ НА ЭКРАН, а не просто объекты дерева BOM) и ВПЛЕТАЮТСЯ в BOM. Я написал «вплетаются», так как создаются еще и промежуточные объекты-контейнеры («неузлы») – например, если пишу элемент
<div id=”first”></div>
, а в него кидаю еще два элемента
<div></div>
, то в BOM два СООТВЕТСТВУЮЩИХ объекта div будут лежать не на первом уровне вложенности, а на ВТОРОМ по отношению к первому объекту div – в «более упорядоченном» объекте-посреднике, на который ссылается свойство
document.getElementById(“first”).childNodes;
. Плюс, стилевая часть содержимого моего хтмл-документа образует другое дерево – дерево CSSOM, которое также «вплетается» (вкладывается) в BOM. Это дерево объектов, которые НЕ ОТОБРАЖАЮТСЯ на экране (а помогают понять браузеру, как отобразить объекты-узлы DOM, которые отображаются на экране). Деревья DOM и CSSOM входят в общее дерево BOM.
Когда я пишу разметку, то для ЧИТАБЕЛЬНОСТИ я ее форматирую – делаю табуляцию, пробелы могу поставить и переводы строк МЕЖДУ ЭЛЕМЕНТАМИ. Эти табуляции, пробелы и переводы строк браузер и перегоняет в текстовые узлы DOM. Например, если я напишу такой код:
<!DOCTYPE HTML><html><head><style>.qq{width:100px;height:100px;border:1px solid black;}</style></head><body><div class="qq" id="first">1</div><div class="qq" id="second">2</div></body></html>
То есть, код БЕЗ ТАБУЛЯЦИЙ И ПЕРЕВОДОВ СТРОК, то эти загадочные текстовые объекты-узлы дерева DOM ИСЧЕЗНУТ (если взять, например, и посмотреть «более упорядоченный» объект-список объектов-узлов-детей объекта-узла body из кода выше, то там будет только два объекта div, а текстовых объектов-узлов уже не будет). Но такой код нечитабельный совсем, поэтому надо их либо удалять, либо задавать им font-size:0px. Плюс, еще надо помнить, что, если у меня объект-узел является inline-block, то он подчиняется ЗАКОНАМ СТРОК – этот объект рассматривается, КАК БУКВА. Например, у него появляется верхний отступ межстрочный, и, чтобы его убрать, надо написать line-height:0px.