Задать вопрос
oink
@oink
Профессиональный веб-макакинг

Почему код, запускаемый по загрузке 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'? Как это пофиксить?
  • Вопрос задан
  • 109 просмотров
Подписаться 1 Простой Комментировать
Решения вопроса 1
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Такое поведение может быть связано с тем, что часть контента, в том числе и необходимая для работы этого скрипта, генерируется динамически после загрузки основного документа.
Самый надёжный способ для таких ситуаций - вешать обработчик на родительский элемент, гарантированно присутствующий на момент DOMContentLoaded и использовать всплытие событий.
Второй вариант - искать, в каком месте реально создаётся и добавляется в DOM нужный элемент и вешать обработчик в это месте кода.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
profesor08
@profesor08 Куратор тега JavaScript
Весь js должен подключаться после загрузки html, значит подключай свой тег скрипта в самом конце документа. Тогда гарантированно все загруженные элементы будут готовы к работе. Повторю, вставляй не в теге head, а переде закрывающим тегом </body>.

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

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

Похожие вопросы