Загадка области видимости на JS

Структура данного проекта такая (псевдокод)

<.parent_1 style=pos-abs; z10>
  <.child_1>
  <.child_1>
  <.child_1>
</.parent_1>

<script>
   code..
<script>

<.parent_2 style=pos-abs; z5>
  <.child_2>
  <.child_2>
  <.child_2>
</.parent_2>

В скрипте (который находится между блоками) я по клику успешно запускаю функцию с параметром MouseEvent и без пробем могу получить доступ к parent_2 хоть в верстке скрипт прописан после этого блока.

function click(MouseEvent) {
   
  let children = document.querySelectorAll('.child_1');
  // работает просто отлично
}

Но создав функцию без Этого эвента - до parent_2 и его детей не достучаться.

Вопрос, Существует ли метод написания функции с глобальной областью видимости, так что бы не переносить script под нижний блок?


Ответы (1 шт):

Автор решения: Арман

Почему не работает?

HTML читается сверху вниз. Интерпретатор доходит до скрипта, читает про <.parent_2>, а элемента то не существует - до него пока не дошли.

Как решить?

Самый удобный для мой взгляд - это аттрибут defer...

<.parent_1 style=pos-abs; z10>
  <.child_1>
  <.child_1>
  <.child_1>
</.parent_1>

<script src="ссылка на скрипт" defer></script>

<.parent_2 style=pos-abs; z5>
  <.child_2>
  <.child_2>
  <.child_2>
</.parent_2>

...которая не запускает скрипты, пока все дерево DOM не сгенерирован. Либо если очень хотите без ссылок, прям в html, напишите так:

<.parent_1 style=pos-abs; z10>
  <.child_1>
  <.child_1>
  <.child_1>
</.parent_1>

<script>
  document.addEventListener(`DOMContentLoaded`, () => {
    // code...
  })
</script>

<.parent_2 style=pos-abs; z5>
  <.child_2>
  <.child_2>
  <.child_2>
</.parent_2>

Собственно аттрибут defer делает тоже самое только в теневой DOM.

→ Ссылка