【问题标题】:Why in my case $(document).click directly calls the function rather than attaching an event handler?为什么在我的情况下 $(document).click 直接调用函数而不是附加事件处理程序?
【发布时间】:2021-07-08 20:09:54
【问题描述】:

我在开发一款游戏,我的目标是:当游戏结束时,用户可以通过单击鼠标重新开始游戏。
但是代码$(document).click(startFunction); 的行为类似于startFunction();
我还注意到,如果$(document).click 被添加到“游戏结束”阶段之前的阶段,那么第一个$(document).click 直接调用下一个函数,第二个$(document).click 按预期工作。
我在这里错过了什么?提前致谢。

这是我的 JS 代码。它已被简化,只有与我的问题相关的“外壳”保持不变。

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

【问题讨论】:

  • 为什么要添加和删除点击处理程序。完全没有必要。分配事件侦听器一次,然后在单击执行任何操作时测试布尔值
  • 这也总是正确的if (1) { if (2) {,因为它们是真实的值
  • mplungjan,感谢您查看我的代码。我删除点击处理程序的原因如下:在我的游戏中有 4 个按钮和屏幕的其余部分。用户使用按钮控制游戏,但通过单击屏幕上的任意位置来启动和重新启动游戏。我的想法是仅在游戏结束时才允许在任何地方单击以重新启动它。如果我误解了您的评论,也许您可​​以发布并举例说明您的意思。关于 if 语句,数字代表条件,因为我有两个条件来评估用户的输入。我删除它们并用数字替换它们只是为了简化。

标签: javascript jquery events handler


【解决方案1】:

我已经测试了这段代码,行为发生了变化: return false; 添加在每个事件处理程序的末尾以取消点击事件传播,例如从 .btn 到文档。

<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>

如果没有 return 子句,函数会返回它的默认值 = undefined。 见https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions

【讨论】:

  • Jacouh,感谢您查看我的代码。我会尽快尝试将其合并到我的游戏中,看看它是否能解决问题。
【解决方案2】:

我以前遇到过奇怪的问题。你可以使用

.bind("click", startFn);

而不是

.click(startFn);

【讨论】:

  • Luke Weaver,感谢您查看我的代码。仅供参考 .bind 已弃用,您可能应该使用 .on() 和 .off() 而不是 .bind() 和 .unbind() 但我明白你的意思。我确实尝试了两种方法,结果是一样的。所以我很有信心这不是问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-12-02
  • 1970-01-01
  • 2013-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-27
相关资源
最近更新 更多