oink
@oink
Начинающий похититель кода со StackOverflow

Почему код, запускаемый по загрузке DOM из динамического источника выдает ошибку, но работает, а из статического работает без ошибок?

Добрый день. Есть такой код, с помощью которого находятся все спрятанные блоки-галереи и активируются чекбоксы-"выключатели", ответственные за то, свернута галерея или развернута. DOM строится динамически из PHP (Битрикс, если это важно).

document.addEventListener('DOMContentLoaded', function() {
    var galleries = document.querySelectorAll('.photogallery');
    if (galleries) {
        [].forEach.call(galleries, function (gallery) {
            var toggle = gallery.querySelector('.photogallery-year-toggle');
            var hiddenWrapper = gallery.querySelector('.photogallery-image-wrapper-hidden');

            toggle.addEventListener('click', function (e) {
                e.preventDefault();
                hiddenWrapper.classList.toggle('photogallery-image-wrapper-hidden');
                toggle.classList.toggle('photogallery-year-toggle-open');
            });
        });
    };
});


Этот код отлично отрабатывает, но в консоли сразу по загрузке всегда появляется ошибка: TypeError: toggle is null. Т.е. браузер вроде бы думает, что элемент в переменной toggle не загрузился и отсутствует. Аналогичный код (классы только другие, понятное дело) на статическом сайте работает без ошибок. Это может быть как-то связано с генерацией HTML из PHP, несмотря на проверку 'DOMContentLoaded'? Как это пофиксить?
  • Вопрос задан
  • 106 просмотров
Решения вопроса 1
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Такое поведение может быть связано с тем, что часть контента, в том числе и необходимая для работы этого скрипта, генерируется динамически после загрузки основного документа.
Самый надёжный способ для таких ситуаций - вешать обработчик на родительский элемент, гарантированно присутствующий на момент DOMContentLoaded и использовать всплытие событий.
Второй вариант - искать, в каком месте реально создаётся и добавляется в DOM нужный элемент и вешать обработчик в это месте кода.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
profesor08
@profesor08 Куратор тега JavaScript
Весь js должен подключаться после загрузки html, значит подключай свой тег скрипта в самом конце документа. Тогда гарантированно все загруженные элементы будут готовы к работе. Повторю, вставляй не в теге head, а переде закрывающим тегом </body>.

Если элементы твоей галереи создаются динамически с помощью какого-то js, то вызывай свой код после того, как отработает генерящий контент код. Там наверняка должен быть соответствующий ивент.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы