getElementsByTagName область видимости?
добрый день!
прошу вашей помощи в связи с вот чем: к хтмл странице с несколькими заголовками h1 цепляется внешний скрипт. если в скрипте код 1, то показывается второй заголовок h1 (то есть все ок). если в скрипте код 2, то в консоли undefined. Если в скрипте код №3, то a содержит массив из заголовков h1(что тоже верно). объясните, пожалуйста, в какую сторону у меня кривые руки и почему getElementsByTagName ведет себя по-разному. заранее большое спасибо! код №1 window.onload=function(){ var a = document.getElementsByTagName ("h1") [1]; console.log(a); } код №2 var a = document.getElementsByTagName ("h1") [1]; console.log(a); код №3 var a = document.getElementsByTagName ("h1"); console.log(a); |
getElementsByTagName возвращает NodeList - живую коллекцию элементов, не массив.
Соответственно: код 1: всё ок, вы получаете коллекцию элементов уже после загрузки страницы когда все они уже присутствуют, берёте второй по счёту и передаёте на вывод console.log. console.log выводит его. код 2: вы получаете коллекцию элементов до загрузки страницы, потому на момент вызова пустую, берёте второй элемент пустой коллекции(поскольку его нет то undefined) и передаёте на вывод console.log. console.log выводит undefined. код 3: вы получаете коллекцию элементов до загрузки страницы, потому на момент вызова пустую, и передаёте оную на вывод console.log. Тут кроется подвох. Передаётся коллекция в console.log ссылкой а не копией, и поскольку когда вы смотрите в консоль страница уже успела загрузиться - коллекция успевает к тому времени заполниться элементами загруженной страницы. Потому вы и видите в консоли её элементы. На момент вызова же она также пуста как и в коде 2. Чтобы это увидеть можно преобразовать код 3 к след. виду: var a = Array.prototype.slice.call( document.getElementsByTagName ("h1") ); //преобразуем живой NodeList в статичный массив console.log(a); P.S. Лично мне не слишком нравится такой подход в реализации console.log - удобнее и логичнее было бы при выводе делать полные копии переданных объектов на момент передачи. Наверное такой поход приводил к излишним расходам памяти или просто противоречил стилю js. Так или иначе теперь уже ничего не попишешь, просто надо учитывать, что в консоли мы увидим самое последнее состояние объекта, а не промежуточное. |
большое спасибо за подробное разъяснение!)))
|
Часовой пояс GMT +3, время: 17:27. |