Reputation: 13
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!
Upvotes: 1
Views: 1731
Reputation: 19790
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.
Upvotes: 1
Reputation: 104168
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);
Upvotes: 0