I have a range slider and I want to listen to its change
and input
events. This works fine in most browsers, but in IE 10, there is no input
event firing and change
fires over and over like input
is supposed to. Here is the code:
html:
<input id="slider" type="range" />
js:
window.addEventListener('load', function() {
var input = document.getElementById('slider');
input.addEventListener('input', function(e) {
console.log('input');
});
input.addEventListener('change', function(e) {
console.log('change');
});
});
And here it is on codepen: http://codepen.io/ZevanRosser/pen/YPQVzJ
I'm wondering if there is a workaround for this - a polyfill or some simple trick.
So I figured this out a few days ago and figured I'd post my solution. Basically the trick is to check if you're in IE (using your sniffing method of choice). Then hijack the change
event for range
inputs and fire an input
instead. Then, fire a change
on mouseup
. This seems to work great so far:
(here's a pen http://codepen.io/ZevanRosser/pen/pvWzej)
window.addEventListener('load', function() {
var input = document.getElementById('slider');
input.addEventListener('input', function(e) {
console.log('input');
});
input.addEventListener('change', function(e) {
console.log('change');
});
var fixInputAndChangeEvents = function() {
var currentSlider;
var fireChange = function(e) {
var changeEvent = document.createEvent('Event');
changeEvent.initEvent('change', true, true);
changeEvent.forceChange = true;
currentSlider.dispatchEvent(changeEvent);
};
document.addEventListener('change', function(e) {
var inputEvent;
if (!e.forceChange && e.target.getAttribute('type') === 'range') {
e.stopPropagation();
inputEvent = document.createEvent('Event');
inputEvent.initEvent('input', true, true);
e.target.dispatchEvent(inputEvent);
currentSlider = e.target;
document.removeEventListener('mouseup', fireChange);
document.addEventListener('mouseup', fireChange);
}
}, true); // make sure we're in the capture phase
};
var isIE = function() {
var userAgent = navigator.userAgent;
return userAgent.indexOf('MSIE') !== -1 ||
userAgent.indexOf('Trident') !== -1;
};
if (isIE()) {
fixInputAndChangeEvents();
}
});
There are a few things I changed in the actual version I used on the project I'm working on.
The project uses lodash so at the request of another developer I partialized the fireChange
event and passed the current range
input as the first argument rather than just using the currentSlider
variable. This is basically to avoid collisions - pretty sure a collision isn't possible since you can only slide one slider at a time, but we figured better be safe than sorry.
The project already had IE sniffing, so I used what was already there over what you see here.
It would be nice to somehow figure out if this event behavior exists rather than sniffing for IE, but I couldn't quite figure out how to determine if the event flaw was present.
Anyway, hope that helps if someone else encounters this problem. I think there is still some room for improvement but this works good enough for now.
EDIT:
As mentionned in comment by Justin Smith, IE10 not support conditionnal comment anymore.
Conditional comments are no longer supported
So the code below is correct under IE10 (I will remove bad comment), and this post not respond to the original answer.
ORIGINAL:
With this code, you will be able to do what you want with your ie version:
If your browser is not one of IE version, no ie
class will be found on html
tag. Also, an ie
class will be found and also an ieX
version.
<!DOCTYPE html>
<!--[if IE 6]><html lang="fr" class="ie ie9"><![endif]-->
<!--[if IE 7]><html lang="fr" class="ie ie10"><![endif]-->
<!--[if IE 8]><html lang="fr" class="ie ie11"><![endif]-->
<!--[if gt IE 9]><!--><html lang="fr"><!--<![endif]-->
and below you have:
<input id="slider" type="range" />
After that, into your code, just do that:
input
for all browser.change
for all ie.So
var html = document.getElementsByTagName("html")[0];
slider = document.getElementById("slider"),
input = (html.classList.contains("ie")) "change" : "input";
slider.addEventListener(input, function () {
// Do something;
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With