【问题标题】:Running a function that creates a click event twice causes the click event to happen twice with one click运行创建两次单击事件的函数会导致单击事件发生两次单击
【发布时间】:2021-01-24 16:43:10
【问题描述】:

我正在开发一款游戏,但我在这里简化了功能。

TestA() 旨在在某个对象上创建点击事件。单击该对象时,它会更新一个数组 tester。

点击事件不应该一直存在,这就是为什么我使用TestA() 创建它,然后在TestA() 中将其关闭。

但是,当我背靠背运行两个 TestA() 函数时,数组会在一次单击时更新两次,而不是预期的一次,然后我需要再次单击以进行第二次更新。

我正在尝试测试:

var tester = []

function TestA() {   
  $("someobject").click(function () {
    tester.push("hello")
    $(this).off()
  })
}

TestA()

----> 单独运行一次,一键生成tester = ["hello"]

TestA()
TestA()

------->这两个背靠背运行,一键测试后变成["hello","hello]

我知道 Javascript 会同时评估所有内容(我过去曾发布过类似的问题),但我确实需要确保人们不能在这个游戏中作弊!

同样,我的目标是让TestA() 添加点击事件,让它在点击时工作一次,直到第二个TestA() 再次发出事件。

-我想一种解决方法是让事件侦听器在其函数内部使用“if”来检查是否甚至可以在单击时评估该函数-但我宁愿只创建单击小时间窗口中的事件。

【问题讨论】:

  • TestA() 添加事件处理程序。调用它两次会添加 2 个事件处理程序。第二个不会取代第一个,它们会叠加,即使它们是相同的。在触发事件之前,它们实际上不会执行,因此.off() 功能不会阻止创建 2 个(或更多!)处理程序。当您单击时,任何和所有附加的事件处理程序都将触发 - 在这种情况下为 2。正如您所说,它们同时运行,因此您会得到您所看到的结果。
  • 除了添加和删除事件处理程序之外,另一种选择可能是跟踪状态。最初设置所有处理程序,并在它们触发时测试当前状态以查看它们是否应该做任何事情。举个简单的例子,TestA() 不包括添加事件处理程序(将在页面加载、游戏开始或其他任何情况下添加)或删除它,而只是测试 tester 是否为空。

标签: javascript jquery events jquery-events


【解决方案1】:

这应该可以解决您的问题:

var tester = []

function TestA() {
  // First remove click handler and set a new one
  $("someobject").off("click").one("click", function () {
    tester.push("hello")
  })
}

TestA()

这是 jsfiddle 中的一个小例子https://jsfiddle.net/yusmneb1/

请注意:要实现某种作弊保护,您应该考虑对游戏逻辑进行服务器端验证。 Javascript 可以很容易地被用户操作。以下是有关该主题的问题的链接:How to prevent html/JavaScript code modification

【讨论】:

  • 谢谢!我点击了,一旦它向测试人员推送了一次“你好”,点击就不再注册了。也许我没有正确描述它 - 我正在寻找的是每次运行 testA() 都是它自己的 click 函数的离散应用程序,所以我点击一次并且 ["hello"] 会出现。然后我会再次点击,["hello","hello"] 会出现。我还计划开发服务器端工具,所以也许我的要求是不可能的,我只是希望测试迭代这个函数,看看它是否会工作,尽管它甚至不会是在实际游戏中我不认为是使用的。
  • 不客气。我只是从点击处理程序中删除了$(this).off("click") 行。这成功了,我也更新了 jsfiddle 链接。因此,请检查它现在是否满足您的要求。告诉我。
  • 我还使用了@cars10m 提到的one 函数。我认为这是比在点击处理程序中使用$(this).off("click") 更好的方法。归功于他。请再次检查 JSFiddle 链接。我不想窃取这个想法,但我想最重要的是一个可行且良好的解决方案。
  • jsfiddle 现在包含另一个元素,该元素在单击时调用testA() 函数并向click me 元素添加一个新的单次单击事件。
【解决方案2】:

通过使用 jQuery .one(),你大概可以实现你想要的:关联的事件只会被触发一次:

const arr=[];
function clickOnOff(flag){
  let b=$("button").off("click");
  if(flag) b.one("click",ev=>{
   arr.push("click");
   $("#switch").prop("checked",false);
   console.log(arr)
  });
}
$("#switch").click(function(){clickOnOff(this.checked)});
// even multiple activation will result in a SINGLE click response:
clickOnOff(1);clickOnOff(1);
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<label><input type="checkbox" id="switch" checked /> listening ...</label><br>
<button>click</button>

【讨论】:

    猜你喜欢
    • 2011-01-08
    • 1970-01-01
    • 2017-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多