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

发布于 2024-10-29 02:12:12 字数 889 浏览 6 评论 0原文

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

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

这个问题正在摧毁我。

为了彻底起见,我提供了一个完整的示例。我意识到这有点长。

$(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;
}

我真的很感谢你的帮助!

I've tried to simplify a problem I'm having with the code below. Some of the code relies on jQuery, fyi.

Basically, I expect that when 'New Thing' is clicked, a single alert message will appear. However, if one starts the timer, clicking 'New Thing' results in an unexpected behavior where the number of alert messages that appear is equal to the time elapsed.

This problem is destroying me.

To be thorough, I've included a complete example. I realize it's a bit lengthy.

$(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;
}

I really appreciate the help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

蓝礼 2024-11-05 02:12:12

这是因为你在按钮的单击事件中添加了多个事件处理程序,

function timer(){
    if (timerIsOn) {
      t = setTimeout(mainLoop, 1000);
      counter++;
      $("span").text(counter); // To display the elapsed time 
    } }

如果超时触发,它将执行 mainLoop。这将调用handleInput
和handleInput 将附加事件处理程序连接到单击事件。

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

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

This is because you add multiple eventhandlers to the click event of the buttons

function timer(){
    if (timerIsOn) {
      t = setTimeout(mainLoop, 1000);
      counter++;
      $("span").text(counter); // To display the elapsed time 
    } }

If the timeout fires, it will execute mainLoop. Which will call handleInput
and handleInput connect an additional eventhandler to the click event.

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

Maining if the timer is running and has fired 3 times. Clicking on #new or #timer will call the appropiate function (timerHandle, createThing) 3 times.

只是偏爱你 2024-11-05 02:12:12

问题是您多次注册事件处理程序。每次调用时,

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

您都会注册一个新的事件处理程序。这意味着,当单击 div 时,timerHandle 将运行您在上面调用的次数。您可以使用 unbind 来避免这种情况:

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

The problem is that you register the event handlers numerous times. Every time you call

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

you register a new event handler. This means, that when the div is clicked, timerHandle will run for so many times as the number you have called the above. You can use unbind to avoid this:

$("#timer").unbind('click');
$("#timer").click(timerHandle);
苦妄 2024-11-05 02:12:12

移动:

handleInput();

至:

document ready function

move:

handleInput();

to:

document ready function
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文