Skip to content Skip to sidebar Skip to footer

Incrementing Value Continuously On Mouse Hold

I have an HTML5 'range' control to which I want to add a plus (+) and minus (-) buttons on either sides. The fiddle works fine, except that the value increase (or decrease) only on

Solution 1:

You can use requestAnimationFrame to constantly check if any button is still pressed. If still pressed, you can increment or decrement your value.

  • Create a 'number' variable that starts at zero.
  • If the Add button is pressed, set an 'isDown' variable to 1.
  • If the Subtract button is pressed, set the 'isDown' variable to -1.
  • If any button is released, set the 'isDown' variable to 0;
  • Start a requestAnimationFrame loop that constantly checks if 'isDown' is not zero. If not zero, requestAnimationFrame changes the 'number' variable by the isDown value.

Here's example code and a Demo:

var $result=$('#result');
var number=0;
var isDown=0;
var delay=250;
var nextTime=0;

requestAnimationFrame(watcher);

$("button").mousedown(function(e){handleMouseDown(e);});
$("button").mouseup(function(e){handleMouseUp(e);});
$("button").mouseout(function(e){handleMouseUp(e);});


functionhandleMouseDown(e){
  // tell the browser we're handling this event
  e.preventDefault();
  e.stopPropagation();

  // Put your mousedown stuff here
  isDown=(e.target.id=='Add')?1:-1;
}

functionhandleMouseUp(e){
  // tell the browser we're handling this event
  e.preventDefault();
  e.stopPropagation();

  // Put your mouseup stuff here
  isDown=0;
}

functionwatcher(time){
  requestAnimationFrame(watcher);
  if(time<nextTime){return;}
  nextTime=time+delay;
  if(isDown!==0){
    number+=isDown;
    $result.text(number);
  }
}
<scriptsrc="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script><buttonid=Add>Add</button><buttonid=Subtract>Subtract</button><spanid='result'>0</span>

Solution 2:

Edit, Updated

Try

var range = $("#range")
, fx = function(elem, prop) {
  return elem
    .animate({
      value: range.prop(prop)
    }, {
      duration: 3000,
      easing: "linear",
      step: function(now) {
             elem.val(now + prop === ("max","+"||"min","-") + elem.prop("step"))
      }
    })
};

$('#plus').mousedown(function(e) {
  fx(range, "max")
});

$('#minus').mousedown(functionminus(e) {
  fx(range, "min")
});

$(document).mouseup(function(e) {
  range.stop(true, false)
});

jsfiddle http://jsfiddle.net/bnesu3h9/3/

var range = $("#range")
, fx = function(elem, prop) {
  return elem
    .animate({
      value: range.prop(prop)
    }, {
      duration: 3000,
      easing: "linear",
      step: function(now) {
        elem.val(now + prop === ("max","+"||"min","-") + elem.prop("step"))
      }
    })
};

$('#plus').mousedown(function(e) {
  fx(range, "max")
});

$('#minus').mousedown(functionminus(e) {
  fx(range, "min")
});

$(document).mouseup(function(e) {
  range.stop(true, false)
});
#plus {
  width: 15px;
  height: 15px;
  background-color: red;
  float: left;
}
#minus {
  width: 15px;
  height: 15px;
  background-color: blue;
  float: left;
}
.range-container {
  float: left;
  overflow: auto;
}
<scriptsrc="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script><inputtype='button'id='minus' /><divclass='range-container'><inputid='range'type='range'min='0'max='100'step='1' /></div><inputtype='button'id='plus' />

Solution 3:

This answer should help.

The click event includes mouseup and mousedown. You'll want to handle mousedown alone at first, and continuously check to see if the mouse is still down. You can stop checking on document mouseup.

Solution 4:

The very basic approach to this is to start looping at certain interval while one of buttons is pressed, doing value changes at each tick. Start when button is clicked, stop when it's released. Here's simplistic code for concept demonstration purpose only:

// Store the referencevar range = $('#range');

// These functions will change the valuefunctionincrement () {
    range.val(parseInt(range.val()) + 1)
}

functiondecrement () {
    range.val(parseInt(range.val()) - 1)
}

// Attaches polling function to elementfunctionpoll (el, interval, fn) {
    var isHeldDown = false;

    return el
    .on("mousedown", function() {
        isHeldDown = true;

        (functionloop (range) {
            if (!isHeldDown) return; // Stop if it was releasedfn();
            setTimeout(loop, interval); // Run the function again       
        })();
    })
    .on("mouseup mouseleave", function () {
        isHeldDown = false; // Stop polling on leave or key release
    });
}

poll($("#plus"), 40, increment);
poll($("#minus"), 40, decrement);

JSFiddle.

In production grade version you'd want to apply timing function instead of constant interval; think about all possible events that should start and stop the polling so it won't stuck forever when user moves pointer away or something; use requestAnimationFrame to control timing function more precisely.

Solution 5:

this is a question that is asked a lot. I have answered on a duplicate thread with a working snippet that exactly does what you are looking for.

https://stackoverflow.com/a/70957862/13795525

functionimposeMinMax(el) {
    if (el.value != '') {
        if (parseInt(el.value) < parseInt(el.min)) {
            el.value = el.min;
        }
        if (parseInt(el.value) > parseInt(el.max)) {
            el.value = el.max;
        }
    }
}


var index = 0;
var interval;
var timeout;
var stopFlag=false;

functionclearAll(){
   clearTimeout(timeout);
   clearInterval(interval);
}


functionmodIn(el) {
   var inId = el.id;
   if (inId.charAt(0) == 'p') {
      var targetId = inId.charAt(2);      
      var maxValue = Number(document.getElementById(targetId).max);
      var actValue = Number(document.getElementById(targetId).value);
      index = actValue;
      if(actValue < maxValue){
         stopFlag=false;
         document.getElementById(targetId).value++;
      }else{
      stopFlag=true;
      }
      timeout = setTimeout(function(){
      interval = setInterval(function(){        
         if(index+1 >= maxValue){
            index=0;
            stopFlag=true;
         }  
         if(stopFlag==false){
            document.getElementById(targetId).value++;
         } 
         index++;
      }, 100);
      }, 500);      
   imposeMinMax(document.getElementById(targetId));
   }
   if (inId.charAt(0) == 'm') {
      var targetId = inId.charAt(2);
      var minValue = Number(document.getElementById(targetId).min);
      var actValue = Number(document.getElementById(targetId).value);
      index = actValue;
      if(actValue > minValue){
         stopFlag=false;
         document.getElementById(targetId).value--;
      }else{
         stopFlag=true;
      }
      timeout = setTimeout(function(){
         interval = setInterval(function(){        
            if(index-1 <= minValue){
               index=0;
               stopFlag=true;
            }  
            if(stopFlag==false){
               document.getElementById(targetId).value--;
            } 
            index--;
         }, 100);
         }, 500);      
      imposeMinMax(document.getElementById(targetId));
   }
}
<!DOCTYPE html><htmllang="en"><head><title>Button example</title><metacharset="utf-8"><linkhref="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3"crossorigin="anonymous"></head><body><buttontype='button'class='btn btn-danger btn-sm 'id='mbA'onmousedown='modIn(this)'onmouseup='clearAll()'>-</button><inputtype='number'id='A'onchange='imposeMinMax(this)'value='200'max='350'min='150'step='1'style='width: 50px;'><buttontype='button'class='btn btn-danger btn-sm 'id='pbA'onmousedown='modIn(this)'onmouseup='clearAll()'>+</button>&nbsp;<buttontype='button'class='btn btn-danger btn-sm signBut'id='mbB'onmousedown='modIn(this)'onmouseup='clearAll()'>-</button><inputtype='number'id='B'onchange='imposeMinMax(this)'value='250'max='450'min='150'step='1'style='width: 50px;'><buttontype='button'class='btn btn-danger btn-sm 'id='pbB'onmousedown='modIn(this)'onmouseup='clearAll()'>+</button>&ensp;<buttontype='button'class='btn btn-danger btn-sm signBut'id='mbC'onmousedown='modIn(this)'onmouseup='clearAll()'>-</button><inputtype='number'id='C'onchange='imposeMinMax(this)'value='3'max='10'min='1'step='1'style='width: 50px;'><buttontype='button'class='btn btn-danger btn-sm 'id='pbC'onmousedown='modIn(this)'onmouseup='clearAll()'>+</button></body></html>

Post a Comment for "Incrementing Value Continuously On Mouse Hold"