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

Viewed 42

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);
}
2 Answers

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 .

I've had weird issues with this before. You could use

.bind("click", startFn);

instead of

.click(startFn);
Related