Search code examples
javascriptjqueryeventshandler

Why in my case $(document).click directly calls the function rather than attaching an event handler?


I work on a game and my goal is this: when the game is over the user can restart the game with a mouse click.
But the code $(document).click(startFunction); acts like startFunction();.
I also noticed that if $(document).click is added to the stage preceding the "game over" stage, then the first $(document).click calls the next function directly and the second $(document).click works like it supposed to.
What am I missing here? Thanks in advance.

Here is my JS code. It has been simplified with only the "shell" related to my questions remain intact.

dislayedGameDescription();

function gameOver() {
    $(document).off("click");
    // more code...
    $(document).click(moveByComputer);
}

function gameStart() {
    $(document).off("click");
    // more code...
    moveByComputer();
}

function moveByComputer() {
    $(document).off("click");
    // more code... 
    $(".btn").click(moveByUser);
}

function moveByUser() {
    $(".btn").off("click");
    // more code...
    determination();
}

function determination() {
    if (1) {
        if (2) {
            moveByComputer();
        } else {
            $(".btn").click(moveByUser);
        }
    } else {
    
    // I want to place here gameOver(); but it works only if I place
    $(document).click(gameOver);

    // And it acts like gameOver(); here so the next $(document).click in the gameOver function acts normal
    }
}

function dislayedGameDescription() {
    // more code...
    $(document).on("click", gameStart);
}

Solution

  • I've tested this code, the behaviour changed: return false; is added at the end of each event handler to cancel click event propagation, from .btn to document for example.

    <html>
    <head>
      <script src="//code.jquery.com/jquery-3.6.0.min.js"></script>
      <script>
    
        function gameOver() {
          console.log("gameOver()");
          $(document).off("click");
        // more code...
          $(document).click(moveByComputer);
          return false;
        }
    
        function gameStart() {
          console.log("gameStart()");
          $(document).off("click");
        // more code...
          moveByComputer();
          return false;
        }
    
        function moveByComputer() {
          console.log("moveByComputer()");
          $(document).off("click");
          // more code...
          $(".btn").click(moveByUser);
          return false;
        }
    
        function moveByUser() {
          console.log("moveByUser()");
          $(".btn").off("click");
          // more code...
          determination();
          return false;
        }
    
        function determination() {
          console.log("determination()");
          if (false && 1) {
            if (2) {
              moveByComputer();
            } else {
              $(".btn").click(moveByUser);
            }
          } else {
            // I want to place here
            gameOver();
            // But it works only if I place
            //$(document).click(gameOver);
            // ...and it acts like gameOver(); here 
            // so the next $(document).click in 
            // the gameOver function acts normal
          }
          return false;
        }
    
    
        function dislayedGameDescription() {
          console.log("dislayedGameDescription()");
          // more code...
          $(document).on("click", gameStart);
          return false;
        }
    
        $(document).ready(function() {
          dislayedGameDescription();
        });
      </script>
    </head>
    
    <body>
    
    <button class="btn">Click button</button>
    
    </body>
    </html>
    

    Without return clause, a function returns it's default value = undefined. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions .