onChange event for HTML5 range

HtmlFormsRangeOnchange

Html Problem Overview


Currently the onChange event on my range inputs is firing at each step.

Is there a way to stop this event from firing until the user has let go of the slider?

I'm using the range to create a search query. I want to be able to run the search every time the form is changed but issuing a search request at each step of the slider's movement is too much.


Here's the code as it stands:

HTML:

<div id="page">
    <p>Currently viewing page <span>1</span>.</p>
    <input class="slider" type="range" min="1" max="100" step="1" value="1" name="page" />
</div>

JavaScript:

$(".slider").change(function() {
    $("#query").text($("form").serialize());
});

Does that help?

Html Solutions


Solution 1 - Html

Use for final selected value:

 $(".slider").on("change", function(){console.log(this.value)});

Use to get incremental value as sliding:

$(".slider").on("input", function(){console.log(this.value)});

Solution 2 - Html

Bit late, but I had the same problem the other day. Here is my solution using jQuery bind/trigger:

(function(el, timeout) {
	var timer, trig=function() { el.trigger("changed"); };
	el.bind("change", function() {
		if(timer) {
			clearTimeout(timer);
		}
		timer = setTimeout(trig, timeout);
	});
})($(".slider"), 500);

Now just bind your function to the 'changed' event instead.

Solution 3 - Html

Bah!

Use onmouseup event Rather then onChange

Solution 4 - Html

One problem is that AFAIK the HTML5 doesn't define when the onchange event is supposed to fire, so it is most likely different from browser to browser. And you also have to consider, that a browser doesn't actually have to render an input type=range as a slider.

Your only choice is that you have to build in a mechanism to make sure that your search isn't triggered too often, for example, check if a search is currently running and abort if it is, or make sure that searches are triggered at a maximum of every x seconds.

Quick example for the latter (just a quick hack, untested).

var doSearch = false;

function runSearch() {
   // execute your search here 
}

setInterval(function() {
  if (doSearch) {
     doSearch = false;
     runSearch();
  }
}, 2000); // 2000ms between each search.

yourRangeInputElement.onchange = function() { doSearch = true; }

Solution 5 - Html

Pure JS here:

myInput.oninput = function(){
    console.log(this.value);
}

or

myInput.onchange = function(){
    console.log(this.value);
}

Solution 6 - Html

gravediggin but if you need it check js throttle or debounce functions

Usage:

//resize events gets processed 500ms after the last Event
addEventListener("resize", _debounce(function(){ foo;}, 500));

//resize events get processed every 500ms
addEventListener("resize", _throttle(function(){ foo;}, 500));

Code:

/*waits 'delay' time after the last event to fire */
_debounce = function(fn, delay) {
    var timer = null;
    return function() {
        var context = this,
            args = arguments;
        clearTimeout(timer);
        timer = setTimeout(function() {
            fn.apply(context, args);
        }, delay);
    };
};


/* triggers every 'treshhold' ms, */
_throttle = function(fn, threshhold, scope) {
    threshhold = threshhold || 250;
    var last,
        deferTimer;
    return function() {
        var context = scope || this;

        var now = +new Date(),
            args = arguments;
        if (last && now < last + threshhold) {
            // hold on to it
            clearTimeout(deferTimer);
            deferTimer = setTimeout(function() {
                last = now;
                fn.apply(context, args);
            }, threshhold);
        } else {
            last = now;
            fn.apply(context, args);
        }
    };
};

Solution 7 - Html

Here's what I use for capturing the 'change event' for the html5 range slider:

HTML:

<form oninput="output1.value=slider1.value">
    <input type="range" name="slider1" value="50"/>
    <output name="output1" for="slider1">50</output>
</form>

JavaScript:

var $slider = $('input[name="slider1"]');
	        
$slider.bind('change', function(e) {
    e.preventDefault();
    console.log($(this).val());
});

You can also bind the 'click' event to the range slider if you want to return its value when it has been clicked (or even dragged). Think of it like a 'mouseup' event. (I did try that but the slider didn't stop after I had clicked on the slider.)

JavaScript:

$slider.bind('click', function(e) {
    e.preventDefault();
    console.log($this).val());
}

On a side note, this returns a string so make sure you use 'parseInt($(this).value())' when appropriate.

Hope this helps.

Solution 8 - Html

I use several HTML5 default sliders in the same page with the following setup:

  • Output tag in the page changes value when the slider is moved using the oninput event
  • A change event is triggered once on release

Tested with the latest Chrome and compiles well on a Raspberry with Node and Socket.io.

<output id="APIDConKpVal"></output>&nbsp; <input type="range"
             class="PIDControlSlider"
             min="0"
             max="1500"
             step="1"
             id="APIDConKp"
             oninput="APIDConKpVal.value=value"/>

<output id="APIDConKiVal"></output>&nbsp; <input type="range"
             class="PIDControlSlider"
             min="0"
             max="2000"
             step="1"
             id="APIDConKi"
             oninput="APIDConKiVal.value=value"/>

A simple Javascript code creates the listeners. You might need to try different events instead of 'change' in the last line to see what fits you.

window.onload=function()
{
 var classname = document.getElementsByClassName("PIDControlSlider");

    var myFunction = function() {
        var attribute = this.getAttribute("id");
//Your code goes here
        socket.emit('SCMD', this.getAttribute("id")+' '+ this.value);
    };

    for(var i=0;i<classname.length;i++){
        classname[i].addEventListener('change', myFunction, false);
    }
}

Solution 9 - Html

another suggest:

$(".slider").change(function(){    
  if (this.sliderTimeour) clearTimeout(this.sliderTimeour);
  this.sliderTimeour = setTimeout(function(){
    //your code here
  },delayTimeHere);
});

Solution 10 - Html

You can try to use blur event. Of course it also has it's limitations but it's just another suggestion :)

You can also try to combine the blur, onkeyup and onmouseup events to try to catch different situations: blur when the user makes the selection with keybord arrows and hits <Tab>, onkeyup when the user makes the selections with keyboard and stays focused on the slider, and onmouseup when he uses the mouse. It might be even possible to only combine the onkeyup and onmouseup.

Still you will have to make a simple check if the value has changed or not and run neccessary code only after a change occured.

Solution 11 - Html

onchange works just fine , but I needed to update the value while sliding it.

var interval;
$("#rangeinput").mousedown(function(event){
    interval = setInterval(function(){
        $("#output").html($("#rangeinput").val());
        console.log("running");
    },150);
});

$("#rangeinput").mouseup(function(event){
    clearInterval(interval);
});

http://jsbin.com/vibuc/1/

Solution 12 - Html

Let's add a simple ES6 alternative to the collection:

let timer;

const debounceChange = (value, callback) => {
    clearTimeout(timer);
    timer = setTimeout(() => callback(value), 500);
};

When used in JSX it would look like this:

<input type="range" onChange={e => debounceChange(e.target.value, props.onChange)}/>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionWilliamMayorView Question on Stackoverflow
Solution 1 - Htmlkravits88View Answer on Stackoverflow
Solution 2 - HtmlArwynView Answer on Stackoverflow
Solution 3 - HtmlToastarView Answer on Stackoverflow
Solution 4 - HtmlRoToRaView Answer on Stackoverflow
Solution 5 - Htmluser3238648View Answer on Stackoverflow
Solution 6 - Htmlmons droidView Answer on Stackoverflow
Solution 7 - HtmlScottView Answer on Stackoverflow
Solution 8 - HtmlPaoloView Answer on Stackoverflow
Solution 9 - HtmlSagiv OfekView Answer on Stackoverflow
Solution 10 - HtmlMichal TrojanowskiView Answer on Stackoverflow
Solution 11 - HtmlalejandroView Answer on Stackoverflow
Solution 12 - HtmlMarco KerwitzView Answer on Stackoverflow