16
var mdflag;
var count = 0;

document.addEventListener("mousedown",mdown,false);
    document.addEventListener("mouseup",mup,false);
}


function mdown()
{
    mdflag=true;
    while(mdflag)
    document.getElementById("testdiv").innerHTML = count++;

}
function mup()
{
    mdflag = false;
}

I'm wanting to run code while the mouse is down, i cant find anything to suggest i can do while(mousedown) so i've tryed making a flag for mousedown which is reset on mouse up however i beleive the while loop is whats causing me to go get stuck in an infinite loop.

Any advice to help with what i'm trying to acheive?

Larry
  • 1,231
  • 4
  • 12
  • 18

3 Answers3

21

You have to invoke the mousedown activity in some reasonable interval. I'd do this:

var mousedownID = -1;  //Global ID of mouse down interval
function mousedown(event) {
  if(mousedownID==-1)  //Prevent multimple loops!
     mousedownID = setInterval(whilemousedown, 100 /*execute every 100ms*/);


}
function mouseup(event) {
   if(mousedownID!=-1) {  //Only stop if exists
     clearInterval(mousedownID);
     mousedownID=-1;
   }

}
function whilemousedown() {
   /*here put your code*/
}
//Assign events
document.addEventListener("mousedown", mousedown);
document.addEventListener("mouseup", mouseup);
//Also clear the interval when user leaves the window with mouse
document.addEventListener("mouseout", mouseup);
Tomáš Zato
  • 50,171
  • 52
  • 268
  • 778
  • Can i ask why -1 is used as apposed to 0? – Larry Mar 19 '13 at 17:07
  • I'm not sure if id of 0 may exist - and I'm used to use `-1` for `null` values. In javascript, you can directly set `mousedownID = null` and ask `if(mousedownID===null)` (checking datatype with `===` for sure). – Tomáš Zato Mar 19 '13 at 17:40
  • 2
    @TomášZato Btw, you don't necessarily have to test for `null` before calling `clearInterval()`. As with [`clearTimeout()`](https://developer.mozilla.org/en-US/docs/DOM/window.clearTimeout#Notes): "*Passing an invalid ID [...] does not have any effect (and doesn't throw an exception).*" Though these methods aren't actually standardized, nearly all current implementations follow this. – Jonathan Lonowski Mar 19 '13 at 18:42
  • Good from you to point this out. But it is still discutatible, if `clearTimeout` checks the ID faster than `==` operator. It may, for example, loop through an array of timeout ID's, That would be slower. – Tomáš Zato Mar 19 '13 at 18:49
  • This doesn't really work that well because the `event` isn't being updated. – PugsAreCute May 22 '21 at 13:15
  • @PugsAreCute Can you elaborate? – Tomáš Zato May 23 '21 at 14:35
  • The event doesn't update on each iteration, so for example `event.clientX` would always stay the same. – PugsAreCute May 23 '21 at 15:26
  • @PugsAreCute There is no global "event" variable in the first place. If you want to track mouse position, you need to listen on mousemove event. – Tomáš Zato May 23 '21 at 20:01
6

You can't do that, as your function must end before another event is processed, but you could repetitively call a function until the mouse is up :

var timer;
document.addEventListener("mousedown", function(){
     timer=setInterval(function(){
          document.getElementById("testdiv").innerHTML = count++;
     }, 100); // the above code is executed every 100 ms
});
document.addEventListener("mouseup", function(){
    if (timer) clearInterval(timer)
});
drunken bot
  • 486
  • 3
  • 8
  • 1
    You could also declare `timer` in the outside scope, as the OP was doing with `mdflag`, and move the `mouseup` event out of `mousedown` so it isn't continuing to add more of them. – Jonathan Lonowski Mar 19 '13 at 16:44
  • Did you think what will happen, if I press the button and leave window? – Tomáš Zato Mar 19 '13 at 16:45
-1

You need to use setInterval to execute your function and clearInternal to stop

let interval = setInterval(function(){
    console.log("executing...");
}, 0);


document.addEventListener("mouseup", function(){
    clearInterval(interval); 
    console.log('End'); 
});