Javascript-форум (https://javascript.ru/forum/)
-   Javascript под браузер (https://javascript.ru/forum/css-html/)
-   -   Добавление нового HTML тега в HTMLCollection (https://javascript.ru/forum/css-html/72683-dobavlenie-novogo-html-tega-v-htmlcollection.html)

Валерия_05 18.02.2018 17:27

Добавление нового 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);

    }


Проверка работает, но толку то от нее. Как обратится к коллекции у которой [] и что-то в нее добавить я не понимаю.

Aetae 18.02.2018 23:45

В первом случае 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.

Валерия_05 19.02.2018 09:44

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, вот только-только два дня назад начала интересоваться этим замечательным языком программирования.

ksa 19.02.2018 10:02

Цитата:

Сообщение от Валерия_05
или что-то можно сделать более оптимально/проще/... ?

Как вариант...

<!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>

Валерия_05 19.02.2018 10:06

ksa, спасибо, но как я уже говорила выше, я пока не использую jQuery и изучаю чистый js.

рони 19.02.2018 10:17

Валерия_05,
в коде ksa, не используется
Цитата:

Сообщение от Валерия_05
jQuery


рони 19.02.2018 10:23

Цитата:

Сообщение от Валерия_05
Вот это - querySelectorAll, я так поняла jQuery?

нет
https://developer.mozilla.org/ru/doc...erySelectorAll

Aetae 20.02.2018 00:51

Цитата:

Сообщение от Валерия_05 (Сообщение 478514)
Вот это - querySelectorAll, я так поняла jQuery?

Как уже заметили выше - это чистый js. Запрос по css селектору. Так как работает с ie8 - можно спокойно использовать.


Цитата:

Сообщение от Валерия_05 (Сообщение 478514)
Это нормальный код или что-то можно сделать более оптимально/проще/... ?

Код нормальный, проще некуда. Суть его в том, что он(из паранойи:)) проверяет не загружен ли уже документ на момент вызова и если да - то сразу вызывает переданную функцию, не вешая бесполезного в таком случае слушателя на событие загрузки, т.к. сие событие уже произошло и повторяться не будет.
Если скрипты подключаются в head без асинхронной загрузки (атрибут async) - можно смело забить и просто вешать слушателя.)


Часовой пояс GMT +3, время: 16:45.