Добавление нового HTML тега в HTMLCollection
Вложений: 2
Всех еще раз приветствую!
Ребзя, помогите понять кое-что. Вот есть такая коллекция Вложение 3782 То что изображено на изображении выше, это я взяла из консоли хрома. Чтобы добавить новый HTML тег, к этой коллекции обращаюсь вот так: var table = document.getElementsByTagName('h1'); table[0].insertBefore(myNewElement, table.childNodes); Всё прекрасно работает. Иногда эта коллекция выглядит вот так Вложение 3783 Вот тут и засада. Я не понимаю как тогда добавить myNewElement Я сделала вот такую проверку: var table = document.getElementsByTagName('h1'); if (table[0] === undefined) { //Не знаю как обратиться к этой коллекции } else{ table[0].insertBefore(myNewElement, table.childNodes); } Проверка работает, но толку то от нее. Как обратится к коллекции у которой [] и что-то в нее добавить я не понимаю. |
В первом случае h1 в документе появился раньше, чем был вызван console.log, во втором позже. Т.е. на момент вызова второго кода никакого h1 ещё не существует. Javascript выполняется последовательно сразу как только получен, и если тег script выше в тексте чем h1, то код из script выполнится уже тогда, когда h1 ещё летит к вам по сети.
Соответственно надо либо дожидаться загрузки страницы (события load или DOMContentLoaded) или ставить тег script в самом низу. Если же ваш h1 и вовсе добавляется динамически, то, соответственно, и изменения надо вносить в ту часть кода, что за это действие отвечает. P.S. В консоли видны все значения потому, что getElementsByTagName (в отличение от например querySelectorAll) возвращает динамическую коллекцию, которая автоматически актуализируется, а когда вы смотрите в консоль страница уже полностью прогрузилась. С этим, кстати, надо быть острожным, т.к. консоль сохраняет лишь примитивные значения (текст\число\булево), копии же объектов не делает оставляя только ссылку, а потому при логировании объекта вы увидите финальные значения на конец исполнения, а не значения на момент вызова console.log. P.P.S. table[0].insertBefore(myNewElement, table.childNodes);это не верно, т.к.: var insertedElement = parentElement.insertBefore(newElement, referenceElement); // insertedElement Вставленный элемент. // parentElement Родитель для нового элемента. // newElement Элемент для вставки. // referenceElement Элемент, перед которым будет вставлен newElement.Как можно видеть referenceElement - должен быть именно элементом, а не ещё одной коллекцией(childNodes). В вашем случае всё работает лишь из-за второй ошибки:): table.childNodes у вас undefined(т.е. не имеет значения), т.к. table - это коллекция(т.е. подобие массива), у неё нет детей, дети бывают только у элементов. А вызов insertBefore с referenceElement, значение которого можно привести к null, равносилен вызову appendChild, т.е. простому добавление insertedElement в конец parentElement. |
Aetae, ой! Спасибо вам за столь развернутый ответ.
Попробую теперь разобраться со всем этим опираясь на информацию, которую вы дали. С меня + в карму. Сейчас пока не могу этого сделать, раздала всё)) Вот это - querySelectorAll, я так поняла jQuery? Я туда даже не смотрю пока. Разбираюсь по максимуму в чистом js и jQuery не использую. Да, знаю что там проще некоторые вещи, но все равно, я пока в основах решила разобраться. Кстати, по поводу события load или DOMContentLoaded. Я на просторах интернета нашла вот такой способ получения того момента, когда страница и дерево полностью загружено: var ready = function (fn) { if (typeof fn !== 'function') return; //Если документ уже загружен, выполнить метод if (document.readyState === 'complete') { return fn(); } //Ждем загрузки документа document.addEventListener( 'DOMContentLoaded', fn, false ); }; ready(function() { //Тут код } Тут как я поняла через хендлер ждем DOMContentLoaded? Это нормальный код или что-то можно сделать более оптимально/проще/... ? Опять же, извините за возможно очень примитивные вопросы. Я пока ни бум-бум в js, вот только-только два дня назад начала интересоваться этим замечательным языком программирования. |
Цитата:
<!DOCTYPE html> <html> <head> <meta http-equiv='Content-Type' content='text/html; charset=windows-1251' /> <!-- <script src='https://code.jquery.com/jquery-latest.js'></script> <script src="https://code.angularjs.org/1.3.9/angular.min.js"></script> <script src="https://code.angularjs.org/1.3.9/angular-route.js"></script> --> <style type='text/css'> </style> <script type='text/javascript'> document.addEventListener('DOMContentLoaded',function(){ alert(document.querySelector('p').innerHTML) }); </script> </head> <body> <p>Пример текста</p> </body> </html> |
ksa, спасибо, но как я уже говорила выше, я пока не использую jQuery и изучаю чистый js.
|
Валерия_05,
в коде ksa, не используется Цитата:
|
Цитата:
https://developer.mozilla.org/ru/doc...erySelectorAll |
Цитата:
Цитата:
Если скрипты подключаются в head без асинхронной загрузки (атрибут async) - можно смело забить и просто вешать слушателя.) |
Часовой пояс GMT +3, время: 16:59. |