30

I need a function that executes a function while a button is pressed and stops executing when the button is let go

$('#button').--while being held down--(function() {
     //execute continuously
}); 
Zebra
  • 3,858
  • 9
  • 39
  • 52
  • Take a look at my question, which is based on this one. There is an improvement to this one: http://stackoverflow.com/questions/36316638/jquery-mousdown-with-setinterval-endless – Steckdoserich Mar 30 '16 at 19:14

4 Answers4

58

I believe something like this would work:

var timeout, clicker = $('#clicker');

clicker.mousedown(function(){
    timeout = setInterval(function(){
        // Do something continuously 
    }, 500);

    return false;
});

$(document).mouseup(function(){
    clearInterval(timeout);
    return false;
});

See this demo: http://jsfiddle.net/8FmRd/

Yi Jiang
  • 49,435
  • 16
  • 136
  • 136
  • 14
    One problem - if you let go off of the hit area, the effect loops forever. You should probably look at having the `mouseup` function on the entire document, rather than just `clicker`. – Jeriko Oct 20 '10 at 11:12
  • Or instead of the setInterval solution he might want to use the mousemove event. – kapa Oct 20 '10 at 11:19
  • @baz Hmmm.. Unlikely, as *any* sort of mouse movement after the button is held would call `clearTimeout`, which generally speaking doesn't seem like the correct behavior here. – Yi Jiang Oct 20 '10 at 11:22
  • @yi There would be no timeout. On mousedown a class would be added to the element, and on mousemove the function would be executed (based on the class). Global mouseup would remove the class. I was thinking he is trying to do some kind of dragging. – kapa Oct 20 '10 at 11:58
  • @YiJiang: FYI -- The demo is hitting a 404 now. – Jordan Arsenault Feb 04 '12 at 22:04
19

A small modification to the original answer:

$('#Clicker').mousedown(function () {
    //do something here
    timeout = setInterval(function () {
        //do same thing here again
    }, 500);

    return false;
});
$('#Clicker').mouseup(function () {
    clearInterval(timeout);
    return false;
});
$('#Clicker').mouseout(function () {
    clearInterval(timeout);
    return false;
});

With the mouseout event on the Clicker it stops when you move your mouse out of the click area.

The reason why I suggest to do the same thing twice is to get a smoother effect. If you don't do it once before the timeout is set it will be a delay of, in this case, 500ms before something happens.

Tarjei Knutsen
  • 191
  • 1
  • 2
3

Here's a pure JavaScript implementation of the supplied solutions which has extended support for touch screens. You supply the id, action to perform (function(){}) and the interval (ms) to repeat the action. Note that this implementation will also execute the action immediately, rather than waiting for the interval to lapse.

// Configures an element to execute a function periodically whilst it holds the user's attention via a mouse press and hold.
function assertPeriodicPress(id, action, interval) {
  // Listen for the MouseDown event.
  document.getElementById(id).addEventListener('mousedown', function(ev) { action(); timeout = setInterval(action, interval); return false; }, false);
  // Listen for mouse up events.
  document.getElementById(id).addEventListener('mouseup', function(ev) { clearInterval(timeout); return false; }, false);
  // Listen out for touch end events.
  document.getElementById(id).addEventListener('touchend', function(ev) { clearInterval(timeout); return false; }, false);
}
Mapsy
  • 4,192
  • 1
  • 37
  • 43
1
$.fn.click2=function(cb,interval){
   var timeout;
   if(!interval) interval=100;
   $(this).mousedown(function () { 
      var target=this;
       timeout = setInterval(function(){
          cb.apply(target);
       }, interval);

    return false;
   }).mouseup(function () {
      clearInterval(timeout);
      return false;
   }).mouseout(function () {
      clearInterval(timeout);
      return false;
   });
}
MajidTaheri
  • 3,813
  • 6
  • 28
  • 46