Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

203
Visualizações
How to access class functions in JS click handler?

I'm creating a card game in HTML, CSS, JS and I have a class PlayerHand that contains functions raiseCard(), lowerCard(), addCards() among others. When I use addCards() SVG images are essentially added to the HTML and I assign a clickHandler to each of the cards.

The click handler on the cards uses the functions raiseCard() and lowerCard() of PlayerHand and it also needs to know which card was clicked, to know which card to raise or lower. The issue I'm having is that when I define the clickHandler inside PlayerHand class, I cannot use the this keyword to access the class functions lowerCard() and raiseCard(). Because this is gonna be the card that I clicked. I'm aware of bind, but I stil need to be able to know the card clicked and access the class functions.

Any idea how I can do this? Am I perhaps designing this in a stupid way?

class PlayerHand {
  
  addCards(cards, eventHandler = null) {
        if (cards.length + this.getCards() > this.MAX_CARDS_ON_HAND) return; // Don't allow more than 13 cards on hand

        cards.forEach((cid) => {
            const card = document.createElement("card-t");
            card.setAttribute("cid", cid);
            card.addEventListener("click", eventHandler, false);
            this.container.appendChild(card);
        });
    }

  raiseCard(cardElement) {
    cardElement.style.transform = "translate(0px, calc(var(--raise-card-on-click) * -1))";
  }

  lowerCard(cardElement) {
    cardElement.style.transform = "none";
  }

  cardClickHandler() {
    const LOWERED = 0;
    let cardHeight = LOWERED;
    const transform = this.style.transform.match(/\d+/g); // Get X and Y coordinate
    if (transform !== null) cardHeight = transform["1"]; // Get the Y coordinate

    if (cardHeight === LOWERED) {
      thisClass.raiseCard(thisCard); // I need to access the class function and pass in the card object that was clicked
    } else {
        thisClass.lowerCard(thisCard); // I need to access the class function and pass in the card object that was clicked
    }
  }
}

Another method I tried was to define the clickHandler outside of the class PlayerHand and then I'd use the player object inside of the click handler, but I didn't quite like this either, as it's not very dynamic by defining the object inside the clickHandler statically.

player = new PlayerHand();

function clickHandler() {
  ...
  if (cardHeight === LOWERED) {
    player.raiseCard(this);
    } else {
      player.lowerCard(this);
  }
}
about 4 years ago · Juan Pablo Isaza
3 Respostas
Responde à pergunta

0

You could just bind the card you want to retrieve with the argument of the click handler function:

class PlayerHand {
  
  addCards(cards, eventHandler = null) {
        // ...
        cards.forEach((cid) => {
            const card = document.createElement("card-t");
            card.setAttribute("cid", cid);
            card.addEventListener("click", this.cardClickHandler.bind(this, card), false);
            this.container.appendChild(card);
        });
    }

  // ...

  cardClickHandler(_event, card) {
    const LOWERED = 0;
    let cardHeight = LOWERED;
    const transform = this.style.transform.match(/\d+/g); // Get X and Y coordinate
    if (transform !== null) cardHeight = transform["1"]; // Get the Y coordinate

    if (cardHeight === LOWERED) {
      this.raiseCard(card); // retrieve here the card you passed as argument in the event handler
    } else {
        this.lowerCard(card); // idem
    }
  }
}
about 4 years ago · Juan Pablo Isaza Relatório

0

As you essentially need two objects (the card element and PlayerHand instance), you'll need two arguments: one can be this, but other should be a normal argument. As the cardClickHandler is defined as a method on the PlayerHand prototype, it would be most natural to let this be the PlayerHand instance.

So attach the event handler as follows:

card.addEventListener("click", () => eventHandler.call(this, card), false);

And then the method would be something like:

  cardClickHandler(card) {
    const LOWERED = 0;
    let cardHeight = LOWERED;
    const transform = card.style.transform.match(/\d+/g);
    if (transform !== null) cardHeight = transform["1"];

    if (cardHeight === LOWERED) {
        this.raiseCard(card);
    } else {
        this.lowerCard(card);
    }
  }
about 4 years ago · Juan Pablo Isaza Relatório

0

When you bind arguments to a function, they get prepended to the arguments that are provided by the caller. So card will be the first argument to cardClickHandler(), before _event provided by addEventListener().

class PlayerHand {
  
  addCards(cards, eventHandler = null) {
        // ...
        cards.forEach((cid) => {
            const card = document.createElement("card-t");
            card.setAttribute("cid", cid);
            card.addEventListener("click", this.cardClickHandler.bind(this, card), false);
            this.container.appendChild(card);
        });
    }

  // ...

  cardClickHandler(card, _event) {
    const LOWERED = 0;
    let cardHeight = LOWERED;
    const transform = this.style.transform.match(/\d+/g); // Get X and Y coordinate
    if (transform !== null) cardHeight = transform["1"]; // Get the Y coordinate

    if (cardHeight === LOWERED) {
      this.raiseCard(card); // retrieve here the card you passed as argument in the event handler
    } else {
        this.lowerCard(card); // idem
    }
  }
}
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda