Ошибка Uncaught TypeError: Cannot read properties of null (reading 'addEventListener') возникает, потому что JavaScript пытается вызвать метод addEventListener на элементе, который равен null. В вашем коде это происходит на строке modal_s.addEventListener или iframe_s.addEventListener, что указывает на то, что либо modal_s, либо iframe_s равны null.
Причина ошибки
- Элемент .modal или iframe не найден в DOM:
- document.querySelector('.modal') возвращает null, если элемент с классом modal отсутствует в DOM на момент выполнения кода.
- Аналогично, если modal_s.querySelector('iframe') не находит <iframe> внутри .modal, то iframe_s будет null.
- Код выполняется до полной загрузки DOM:
- Хотя вы используете событие DOMContentLoaded, возможно, код выполняется в контексте, где DOM ещё не полностью загружен, или структура страницы отличается от ожидаемой.
- Динамическое добавление элементов:
- Если элементы .modal или iframe добавляются в DOM динамически (например, через JavaScript после загрузки страницы), то на момент выполнения вашего кода они могут отсутствовать.
Решение
Чтобы устранить ошибку, нужно добавить проверку на существование элементов перед тем, как вызывать методы на них. Вот исправленный код:
document.addEventListener("DOMContentLoaded", function () {
const modal_s = document.querySelector('.modal');
// Проверяем, существует ли modal_s
if (!modal_s) {
console.error('Элемент .modal не найден в DOM');
return;
}
const iframe_s = modal_s.querySelector('iframe');
// Проверяем, существует ли iframe_s
if (!iframe_s) {
console.error('Элемент iframe не найден внутри .modal');
return;
}
const modalBody_s = document.querySelector('.modal-body');
// Проверяем, существует ли modalBody_s
if (!modalBody_s) {
console.error('Элемент .modal-body не найден в DOM');
return;
}
modal_s.addEventListener('wheel', () => {
iframe_s.style.pointerEvents = 'none';
clearTimeout(iframe_s._scrollTimeout);
iframe_s._scrollTimeout = setTimeout(() => {
iframe_s.style.pointerEvents = 'auto';
}, 350);
});
iframe_s.addEventListener('mouseenter', () => {
modalBody_s.style.overflow = 'hidden';
});
iframe_s.addEventListener('mouseleave', () => {
modalBody_s.style.overflow = 'auto';
});
});Что делает исправленный код
- Проверка на null:
- Перед использованием modal_s, iframe_s и modalBody_s проверяется, существуют ли эти элементы. Если какой-либо из них отсутствует, выводится сообщение об ошибке в консоль, и выполнение кода прекращается (return).
- Логирование для отладки:
- Сообщения в консоли (console.error) помогут вам понять, какой именно элемент не был найден, что упрощает отладку.
Дополнительные рекомендации
- Проверьте структуру HTML:
- Убедитесь, что элементы с классами .modal и .modal-body, а также <iframe> внутри .modal, присутствуют в HTML на момент выполнения скрипта. Пример правильной структуры:
html<div class="modal"><div class="modal-body"><iframe src="..."></iframe></div></div>
- Убедитесь, что элементы с классами .modal и .modal-body, а также <iframe> внутри .modal, присутствуют в HTML на момент выполнения скрипта. Пример правильной структуры:
- Динамическое добавление элементов:
- Если .modal или iframe добавляются динамически (например, через AJAX или JavaScript), вам нужно либо дождаться их появления в DOM, либо использовать делегирование событий. Например, можно использовать MutationObserver для отслеживания изменений в DOM:
javascriptdocument.addEventListener("DOMContentLoaded", function () {const observer = new MutationObserver(() => {const modal_s = document.querySelector('.modal');if (modal_s) {const iframe_s = modal_s.querySelector('iframe');const modalBody_s = document.querySelector('.modal-body');if (iframe_s && modalBody_s) {// Ваш код для добавления обработчиков событийmodal_s.addEventListener('wheel', () => {iframe_s.style.pointerEvents = 'none';clearTimeout(iframe_s._scrollTimeout);iframe_s._scrollTimeout = setTimeout(() => {iframe_s.style.pointerEvents = 'auto';}, 350);});iframe_s.addEventListener('mouseenter', () => {modalBody_s.style.overflow = 'hidden';});iframe_s.addEventListener('mouseleave', () => {modalBody_s.style.overflow = 'auto';});observer.disconnect(); // Отключаем наблюдатель после нахождения элементов}}});observer.observe(document.body, { childList: true, subtree: true });});
- Если .modal или iframe добавляются динамически (например, через AJAX или JavaScript), вам нужно либо дождаться их появления в DOM, либо использовать делегирование событий. Например, можно использовать MutationObserver для отслеживания изменений в DOM:
- Проверьте порядок загрузки скриптов:
- Убедитесь, что ваш скрипт подключается после загрузки HTML-структуры. Например, скрипт можно разместить в конце <body> или использовать атрибут defer:
html<script defer src="your-script.js"></script>
- Убедитесь, что ваш скрипт подключается после загрузки HTML-структуры. Например, скрипт можно разместить в конце <body> или использовать атрибут defer:
- Проблема со скроллингом iframe:
- Если проблема с зависанием скроллинга сохраняется, убедитесь, что стили pointer-events и overflow корректно применяются. Также проверьте, нет ли конфликтов с другими скриптами или стилями, которые могут влиять на поведение модального окна или iframe.
- Отладка:
- Откройте DevTools в браузере (F12) и проверьте консоль на наличие дополнительных ошибок.
- Используйте console.log(modal_s, iframe_s, modalBody_s) перед добавлением обработчиков, чтобы убедиться, что элементы найдены.
Итог
Ошибка возникает из-за отсутствия элементов .modal, iframe или .modal-body в DOM на момент выполнения кода. Исправленный код с проверками на null предотвратит ошибку и поможет диагностировать проблему. Если элементы добавляются динамически, используйте MutationObserver или перенесите код в место, где элементы гарантированно существуют.