-2

if i write like so, things work

var p1Button = document.getElementById("p1Button");
var p1Score = 0;
var p1Span = document.getElementById("p1ScoreSpan");

var p2Button = document.getElementById("p2Button");
var p2Score = 0;
var p2Span = document.getElementById("p2ScoreSpan");

var winningScore = document.querySelector("#targetScore").textContent
var gameOver = false;

//for the reset button
var resetButton = document.getElementById("ResetButton");

p1Button.addEventListener("click", function(){
    // console.log(gameOver)
    if(!gameOver) {
        p1Score++;
        if(p1Score == winningScore) {
            p1Span.classList.add('winner');
            gameOver = true;
        }
        p1Span.textContent = p1Score;
    }

})


p2Button.addEventListener("click", function () {
    console.log(gameOver)
    if (!gameOver) {
        p2Score++;
        if(p2Score == winningScore){
            p2Span.classList.add('winner');
            gameOver = true;
        }}
        p2Span.textContent = p2Score;
})

But to keep it 'DRY' creating a function and using it as the callback doesn't seem to work. Below is the code snippet, that runs ones even without me clicking the 'buttons' defined in HTML

var callBackfunct = function (playerScore, playerSpan) {
    console.log(gameOver)
    console.log(winningScore)
    if (!gameOver) {
        playerScore++;
        if (playerScore == winningScore) {
            playerSpan.classList.add('winner');
            gameOver = true;
        }
    }
    playerSpan.textContent = playerScore;
    console.log(gameOver)
}

p1Button.addEventListener("click", callBackfunct(p1Score, p1Span));

p2Button.addEventListener("click", callBackfunct(p2Score, p2Span));

Where did i err'ed? I am expecting that when i click on the player1 button, the callback function is called by hnouring the if conditions

OK999
  • 1,353
  • 2
  • 19
  • 39
  • 3
    you are imediately calling `callBackfunct`, not returning a new callback function. – Daniel A. White Apr 18 '18 at 17:42
  • 1
    `addEventListener` wants a function reference. You are calling a function and giving it what that function returns, which is `undefined`. – zero298 Apr 18 '18 at 17:42
  • i think i know what you are saying. So to pass the function reference, if there a way to pass the arguments as well. – OK999 Apr 18 '18 at 17:46
  • 1
    @OK999 my answer demonstrates that :) – Joe Warner Apr 18 '18 at 17:47
  • Thanks @JoeWarner ... BTW, SO is too cruel when you are beginning to learn a new language. :) – OK999 Apr 18 '18 at 17:49
  • yeah yeah it is but not because they're being mean its your answer is out there but i know its hard when starting to know what is the issue the more experience you have the better at finding the answers when you get downvoted ask yourself why is it in your case now i think its because its a duplicate. I think i got banned my first week on SO dont be to hard on yourself – Joe Warner Apr 18 '18 at 17:51

2 Answers2

2

you are calling the function straight away add an arrow function and it should work

p2Button.addEventListener("click", () => callBackfunct(p2Score, p2Span));

or non ES6

p2Button.addEventListener("click", function() {
   callBackfunct(p2Score, p2Span)
});

https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener

The event listener can be specified as either a callback function or as an object that implements EventListener, whose handleEvent() method serves as the callback function.

Joe Warner
  • 3,335
  • 1
  • 14
  • 41
  • 1
    You need to do this because `.addEventListener` requires a function reference (no parens) rather than a function call (with parens) as its second argument. Function calls always call functions, and you want to pass the function, not call it. – wassona Apr 18 '18 at 17:45
  • exactly what @wassona said :) good insights – Joe Warner Apr 18 '18 at 17:46
1

Instead of calling the function directly:

 callBackfunct(p1Score, p1Span)

Just create a bound function which you can then pass to the handler, so that the handler can call it later:

 callBackfunct.bind(null, p1Score, p1Span)
Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
  • i got this part of passing the function definition, and not executing it. But any idea why is `playerScore` variable is not incremented inside the function? Chrome console, always shows a value of '1' after the first execution – OK999 Apr 18 '18 at 18:03
  • 1
    @OK999 yes, as JS has *pass by value*, so if you do `sth(a)`, it won't create a reference to a, but it will copy the value of `a` into the local functions variable. – Jonas Wilms Apr 18 '18 at 18:05
  • So you dont actually increase `p1Score` but just `playerScore`, which will get lost when the function is done with its execution. – Jonas Wilms Apr 18 '18 at 18:06
  • Ahh, i see what you are saying. The only thing, that i can think of now, to put the code to get the score from the DOM everytime the function is called. – OK999 Apr 18 '18 at 18:45
  • @OK999 or you pass an object. – Jonas Wilms Apr 18 '18 at 19:16
  • here is the modified function: `var callBackfunct = function (playerScore, playerSpan) { if (!gameOver) { // playerScore++; score = playerSpan.textContent score++; if (score == winningScore) { playerSpan.classList.add('winner'); gameOver = true; } playerSpan.textContent = score; } }` – OK999 Apr 18 '18 at 19:24