1

I'm trying to animate letters in a string one after the other like how dominoes fall. The this keyword inside the handler function refers to window, how can I fix this?

class App {
  constructor() {
    this.mouseTarget = document.querySelector('#target');
    this.letters = document.querySelectorAll('.letter');
    
    this.handler = this.handler.bind(this);

    this.mouseTarget.addEventListener('mouseenter', this.handler, false);
    this.mouseTarget.addEventListener('mouseleave', this.handler, false);
  }

  handler(event) {
    if (event.type === 'mouseenter') {
      setTimeout(function() {
        this.letters.forEach(function(letter) {
          letter.classList.add('active');
        });
      }, 300);
    }
    else if (event.type === 'mouseleave') {
      setTimeout(function() {
        this.letters.forEach(function(letter) {
          letter.classList.add('inactive');
        });
      }, 300);
    }
  }
}
Domino
  • 37
  • 8
  • 1
    `this.mouseTarget.addEventListener('mouseenter', () => this.handler(), false);` – trincot Feb 11 '21 at 20:50
  • 3
    `function() {}` has its own scope in js. If you want the functions inside the setTimeout to use the same scope as the parent object, use "fat arrow" functions instead – Daniel Beck Feb 11 '21 at 20:52
  • 2
    Tried to add an answer but couldn't before question was closed. You're adding a function inside `setTimeout`, which has its own `this` context. Change it to an arrow function, which has no `this` context. Replace the line with `setTimeout(() => {` – Codebling Feb 11 '21 at 20:52

0 Answers0