JavaScript';s setTimeout函数进行意外的多次调用

JavaScript';s setTimeout函数进行意外的多次调用,javascript,jquery,html,settimeout,Javascript,Jquery,Html,Settimeout,我试图简化下面代码中的一个问题。一些代码依赖于jQuery,仅供参考 基本上,我希望当点击“新事物”时,会出现一条警告消息。但是,如果启动计时器,单击“New Thing”(新事物)会导致出现意外行为,其中出现的警报消息数等于经过的时间 这个问题毁了我 为了更全面,我提供了一个完整的示例。我意识到这有点冗长 $(document).ready(function() { mainLoop(); }); var counter = 0; var timerIsOn = 0; var t;

我试图简化下面代码中的一个问题。一些代码依赖于jQuery,仅供参考

基本上,我希望当点击“新事物”时,会出现一条警告消息。但是,如果启动计时器,单击“New Thing”(新事物)会导致出现意外行为,其中出现的警报消息数等于经过的时间

这个问题毁了我

为了更全面,我提供了一个完整的示例。我意识到这有点冗长

$(document).ready(function() { mainLoop(); }); var counter = 0; var timerIsOn = 0; var t; function mainLoop() { handleInput(); timer(); } function timerHandle() { if (!timerIsOn){ timerIsOn = 1; timer(); } } function timer(){ if (timerIsOn) { t = setTimeout(mainLoop, 1000); counter++; $("span").text(counter); // To display the elapsed time } } // Just simple buttons function handleInput(){ $("#timer").click(timerHandle); $("#new").click(createThing); } function Thing() { this.talk(); } Thing.prototype.talk = function() { alert("Hello!"); } function createThing() { new Thing; } $(文档).ready(函数(){ mainLoop(); }); var计数器=0; var-timerIsOn=0; 变量t; 函数mainLoop(){ handleInput(); 定时器(); } 函数timerHandle(){ if(!timerIsOn){ timerIsOn=1; 定时器(); } } 函数计时器(){ if(timerIsOn){ t=设置超时(主循环,1000); 计数器++; $(“span”).text(计数器);//以显示经过的时间 } } //只是简单的按钮 函数handleInput(){ $(“#计时器”)。单击(timerHandle); $(“#新建”)。单击(createThing); } 函数事物(){ 这个.talk(); } Thing.prototype.talk=函数(){ 警惕(“你好!”); } 函数createThing(){ 新事物; }
我真的很感谢你的帮助

问题是您多次注册事件处理程序。每次你打电话

$("#timer").click(timerHandle);
注册一个新的事件处理程序。这意味着,当单击div时,timerHandle将运行与您上面调用的号码相同的次数。可以使用“取消绑定”来避免此情况:

$("#timer").unbind('click');
$("#timer").click(timerHandle);

问题是您多次注册事件处理程序。每次你打电话

$("#timer").click(timerHandle);
注册一个新的事件处理程序。这意味着,当单击div时,timerHandle将运行与您上面调用的号码相同的次数。可以使用“取消绑定”来避免此情况:

$("#timer").unbind('click');
$("#timer").click(timerHandle);

这是因为您向按钮的单击事件添加了多个EventHandler

function timer(){
    if (timerIsOn) {
      t = setTimeout(mainLoop, 1000);
      counter++;
      $("span").text(counter); // To display the elapsed time 
    } }
如果超时触发,它将执行mainLoop。这将称为handleInput 和handleInput将另一个eventhandler连接到click事件

function handleInput(){    
     $("#timer").click(timerHandle); 
     $("#new").click(createThing); }

如果计时器正在运行且已触发3次,则进行维护。单击#new或#timer将调用appropiate函数(timerHandle,createThing)3次。

这是因为您向按钮的click事件添加了多个EventHandler

function timer(){
    if (timerIsOn) {
      t = setTimeout(mainLoop, 1000);
      counter++;
      $("span").text(counter); // To display the elapsed time 
    } }
如果超时触发,它将执行mainLoop。这将称为handleInput 和handleInput将另一个eventhandler连接到click事件

function handleInput(){    
     $("#timer").click(timerHandle); 
     $("#new").click(createThing); }
如果计时器正在运行且已触发3次,则进行维护。单击#新建或#计时器将调用适当的函数(timerHandle、createThing)3次。

移动:

handleInput();
致:

移动:

致:


我在这里提出了一个问题:每次调用mainLoop时,它都会调用handleInput,这会在按钮上添加另一个单击侦听器,因此当您多次单击它时,您会运行越来越多的超时,但只有一个“t”来取消最后一个。这很有意义!出于某种原因,我认为事件处理程序可以被覆盖。谢谢别忘了接受答案!通过单击答案旁边的复选标记来实现这一点,这对您帮助最大。我在这里列出了您的问题:每次调用mainLoop时,它都会调用handleInput,这会在按钮上添加另一个单击侦听器,因此当您多次单击它时,您会运行越来越多的超时,但只有一个“t”取消最后一个。这很有道理!出于某种原因,我认为事件处理程序可以被覆盖。谢谢别忘了接受答案!点击答案旁边的复选标记,这对你帮助最大。哦,孩子!没有意识到可以将多个事件绑定到元素。回过头来看,如果元素只能保留一个事件处理程序,您将失去很多功能。谢谢你,孩子!没有意识到可以将多个事件绑定到元素。回过头来看,如果元素只能保留一个事件处理程序,您将失去很多功能。谢谢谢谢,这就是我最后做的。艾克:以后最好解释一下为什么它不起作用,然后是一个简单的解决方案。谢谢,这就是我最后做的。艾克:以后最好解释一下为什么它不起作用,然后是一个简单的解决方案。谢谢!我决定将handleInput()移动到$(document.ready()。我原本认为我必须特别检查是否触发了事件。那太傻了。当一个事件触发时,无论发生什么,它都会让您知道。谢谢!我决定将handleInput()移动到$(document.ready()。我原本认为我必须特别检查是否触发了事件。那太傻了。当一个事件触发时,无论发生什么,它都会让您知道。