TypeError: невозможно прочитать свойства неопределенного (чтение «addEventListener»)

Я все еще относительно новичок в программировании, поэтому приношу свои извинения, если это имеет очевидное решение. Я пытался отладить этот код. Я прочитал несколько вопросов, связанных с этой addEventListener ошибкой. Кажется, что большинство из них предлагают обеспечить загрузку элементов в DOM до запуска TS.

Чтобы убедиться в этом, я запустил метод под ngAfterViewInit() {}, а также обернул основные функции внутри window.onload = function() {}. Я надеялся, что это решит проблему, но я все еще получаю сообщение об ошибке. Скажу, что функционал TS, HTML, CSS работает как надо. Я навожу курсор на буквы, и буквы меняют цвет и анимируются, однако ошибка меня просто расстраивает. Я включу свой TS, HTML и CSS. Благодарю вас!

constructor() {}

ngOnInit(): void {}

ngAfterViewInit() {
  this.changeClass();
}

changeClass() {

  window.onload = function() {
    const elements = document.getElementsByClassName('wordPop');

    if (elements) {
      for (let i = 0; i <= elements.length; i++) {
        elements[i].addEventListener('mouseover', () => {
          elements[i].classList.add('animated');
        });

        elements[i].addEventListener('animationend', () => {
          elements[i].classList.remove('animated');
        });
      }
h1 {
  font-family: Arial, Helvetica, sans-serif;
  display: inline-block;
}

.blastRubberBand {
  display: inline-block;
  margin-left: 2px;
  margin-right: 2px;
  position: relative;
  font-size: 100px;
  color: rgb(228, 15, 115);
}

.wordPop {
  display: inline-block;
  margin-left: 2px;
  margin-right: 2px;
  position: relative;
  font-size: 100px;
  color: aliceblue;
}

.wordPop.animated {
  color: orange;
  animation: rubberBand 0.7s ease-in-out 1;
}

@keyframes rubberBand {
  from {
    transform: scale3d(1, 1, 1);
  }
  30% {
    transform: scale3d(1.25, 0.75, 1);
  }
  40% {
    transform: scale3d(0.75, 1.25, 1);
  }
  50% {
    transform: scale3d(1.15, 0.85, 1);
  }
  65% {
    transform: scale3d(.95, 1.05, 1);
  }
  75% {
    transform: scale3d(1.05, .95, 1);
  }
  to {
    transform: scale3d(1, 1, 1);
  }
}
<script src = "https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.4/angular.min.js"></script>
<h1 class = "coolLetters">
  <span class = "wordPop">H</span>
  <span class = "wordPop">e</span>
  <span class = "wordPop">l</span>
  <span class = "wordPop">l</span>
  <span class = "wordPop">o</span>
</h1>

🤔 А знаете ли вы, что...
JavaScript поддерживает объектно-ориентированное программирование.


1
31
2

Ответы:

Решено

Проблема в этой строке:

for (let i = 0; i <= elements.length; i++)

Вы получаете эту ошибку, потому что на последней итерации i=elements.length и elements[elements.length] = undefined.

Должен быть :

for (let i = 0; i < elements.length; i++)

Как сказал @yousoumar, вы заходите слишком далеко. Индексы массива начинаются с 0 и заканчиваются с количество элементов - 1. Ошибка, которую вы получаете, вызвана вашей попыткой сослаться на несуществующий индекс в вашем массиве элементов.

Например:

elements = |a|b|c|d|
index =     0 1 2 3 
your last iter = elements[4], which is outside of the index range.