fAntonM
@fAntonM
веб-разработчик, дизайнер

Один файл Javascript на две страницы — ошибка 'addEventListener' of null?

Здравствуйте!

Я начинающий разработчик. Работаю на нативном JS.
Много уже писалось о том, сколько файлов JS использовать в одном проекте ( из более одной страницы).
Я ознакомился с разными вариантами. Но, в ответах нигде не видел пояснений по поводу вот такого случая:
Вариант когда все собрано в одном файле main.js. Проект на 2-100 страниц
Главная страница с классами text и box ( и еще 100 других классов). Подключен внешний файл main.js ( внизу body) с двумя переменными text и box. Добавлен слушатель addEventListener для двух переменных text и box. Клик или console.log - и все работает прекрасно).
Создаем вторую страницу - Контакты. Но только с одним классом text ( и еще 100 других). класса Box в нем нет. Подключаем тот же файл main.js
И, получаем в консоли страницы Контакты ошибку Cannot read property 'addEventListener' of null
Я согласен, что обработчик не может найти класс box на странице контакты. И это естественно. Весь код останавливается и на странице Контакты ничего не работает.
Решение ( для меня): вынести код JS Контактов в отдельный файл или прописать его в самом файле Контактов внизу.
Вопрос: Те разработчики, которые пишут что хранят весь код в JS в одном файле, как это возможно, если все страницы разные - на одной есть Карусель ( без формы), на другой - форма ( без карусели). И у всех классов есть обработчики, которые не видят классы на соседних страницах. Но если хотя бы одного класса не будет найдено на одной из страниц, то мы получим ошибку на этой странице.
Если я захочу добавить кнопку на странице Контакты и навешу на нее обработчик, то ошибка появится на странице index ( Главная) , т.к там такой кнопки нет.

Так как быть? Создавать для каждой страницы отдельные js файлы? Но, это утомительно долго и плодит их количество. А если страниц 100 шт. и на каждой есть небольшие изменения по классам? И на этих классах висят обработчики.

Также можно создать шаблонный файл JS ( шапка, подвал, мобильное меню) который будет точно копироваться на все страницы. Хорошо бы. Но, тогда все равно для страницы Контакты ( и других) нужен или свой отдельный JS или что...? Я добавлю обработчик в Контакты, который не будет виден в Шаблонном файле и опять ошибка?

Пока вижу для себя одно решение для одного файла JS - прописывать разные имена классов для каждой страницы. Не уверен, что это удобно и быстро.

Как бы Вы решили подобную задачу, с учетом приведенного примера?

PS Сборщики не предлагать.))
PPS Пожалуйста, на простых примерах и только из личного опыта)).
  • Вопрос задан
  • 1471 просмотр
Решения вопроса 2
fAntonM
@fAntonM Автор вопроса
веб-разработчик, дизайнер
Здравствуйте, еще раз коллеги!

К сожалению, те ответы, что получил год назад, не подошли мне, т.к. не решали проблему просто и без танцев.
Как оказалось, есть простое решение, которое используют многие разработчики.
Необходимо для участка кода, который может потенциально вызвать ошибку и остановить весь скрипт ниже, применить конструкцию Try-Catch
Ее суть в том, что если в коде обнаружится ошибка, то код отловит эту ошибку, НО продолжит работу.
Подробнее можете посмотреть на MDN.

Теперь еще раз повторю суть проблемы:
Те, кто собирают многостраничный проект без сборщиков, с одним файлом JS и навешивают обработчики на какие то элементы DOM, которых может не быть на других страницах HTML - получат ошибку не тех страницах и код встанет.

Исходные данные и порядок работы:
1. Два файла HTML ( index и contacts) например
2. В index есть элемент с классом text ( и еще сотни других элементов с другими классами)
3. В contacts - нет элемента с классом text ( но могут быть другие классы, не суть)
4. Есть общий (один) файл script.js , он подключен к обоим файлам HTML
5. В js файле находим класс text и навешиваем обработчик - click
6. Открываем index – все Ок
7. Открываем – contacts – видим ошибку - Cannot read properties of null (reading 'addEventListener')
8. Скрипт останавливает свою работу ниже обработчика.

Вот пример кода с ошибкой:
const text = document.querySelector('.text');
// Получаем ошибку при открытии страницы contacts - Cannot read properties of null (reading 'addEventListener')
text.addEventListener('click', ()=> { 
  console.log('result');
 });

 // Дальше код не идет
 console.log('Следующий код'); // не работает


Решение:
Нам необходимо вставить проблемный участок кода в блок Try конструкции try-catch:
const text = document.querySelector('.text');

try {
  text.addEventListener('click', ()=> { 
    console.log('result');
   });
} catch(error) {
console.log(error); // выведет о чем ошибка
//Но, можно ничего не писать вообще в блоке catch
}

 // Дальше код продолжает работу
 console.log('Следующий код'); // Да, работает)
Ответ написан
Stalker_RED
@Stalker_RED
const boxes = document.querySelectorAll('.box');
if (boxes.length) {
   boxes.forEach(box => box.addEventListener('click', myBoxClickHandler));
} else {
  console.log('These aren\'t the boxes you\'re looking for.');
   // на самом деле вся ветка 'else' не нужна
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

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