3

It seems like using the input event on a type=range input element works differently in Webkit and Firefox. I really don't understand why the event fires both on sliding the slider and while releasing the mouse.

I very much do not want the event to fire again when releasing the mouse button.

Any ideas how to stop this mouseup nonsense with the input event?

var counter = document.querySelector('div'),
    rangeInput = document.querySelector('input');

rangeInput.addEventListener('input', function(){
  counter.innerHTML = 1 + +counter.innerHTML;
});
body{ font:18px Arial; }
input{ width:80%; }
div{ color:red; }
div::before{ content:'Event fired: '; color:#555; }
div::after{ content:' times'; color:#555; }
<p>Try to click the slider, wait and release the mouse</p>

<input type="range" min="1" max="100" step="1">

<div>0</div>

Demo page


Update: opened a bug in bugzilla

vsync
  • 118,978
  • 58
  • 307
  • 400
  • In which browser does the problematic `mouseup` event fire? Having tried it in Chrome (51.x, Windows 10) it doesn't seem to be firing, but I don't want to assume that it's Firefox demonstrating the problem. – David Thomas Jul 17 '16 at 10:43
  • problem seems to be on firefox – AL-zami Jul 17 '16 at 10:55
  • @DavidThomas - the same browser which is mentioned in the title – vsync Jul 17 '16 at 11:37

1 Answers1

1

How about listening to the change event instead of input?

As per your example:

var counter = document.querySelector('div'),
    rangeInput = document.querySelector('input');

rangeInput.addEventListener('change', function(){
  counter.innerHTML = 1 + +counter.innerHTML;
});
body{ font:18px Arial; }
input{ width:80%; }
div{ color:red; }
div::before{ content:'Event fired: '; color:#555; }
div::after{ content:' times'; color:#555; }
<p>Try to click the slider, wait and release the mouse</p>

<input type="range" min="1" max="100" step="1">

<div>0</div>

This seems to be a browser bug nevertheless. See this issue posted in react project.

What you could do is to have this as a fallback in browsers that show this behaviour. Detect the browsers that are doing this and have this fallback for them which cancels out the extra increament.

var counter = document.querySelector('div'),
    rangeInput = document.querySelector('input');

rangeInput.addEventListener('input', function(){
  counter.innerHTML = 1 + +counter.innerHTML;
});
 rangeInput.addEventListener('change', function(){
  /* if firefox - http://stackoverflow.com/a/9851769/1437261 */
  if(typeof InstallTrigger !== 'undefined'){
     counter.innerHTML =  counter.innerHTML - 1;
  }
  
  return false;
});
body{ font:18px Arial; }
input{ width:80%; }
div{ color:red; }
div::before{ content:'Event fired: '; color:#555; }
div::after{ content:' times'; color:#555; }
<p>Try to click the slider, wait and release the mouse</p>

<input type="range" min="1" max="100" step="1">

<div>0</div>
Gogol
  • 3,033
  • 4
  • 28
  • 57
  • @dandavis well depends on how he wants it. – Gogol Jul 17 '16 at 10:48
  • This is not a solution.. **(a)** I do not want `change` event **(b)** obviously the I made a demo showing the bug but in reality i don't count anything but perform code which much more complexity which shouldn't be fired **at all** on `mouseup` – vsync Jul 17 '16 at 11:36
  • @vsync obviously it is a bug ( or, i would call it a dissimilarity between the engines). I guess it will be patched sooner or later. All I focused to do here is to have a temporary solution before that. more complex code will need more complex solution. I would gladly solve it if I could, if you post the problem :) – Gogol Jul 17 '16 at 11:43
  • 1
    I am afraid the real code is so complex it is un-postable, because the event triggers events of other components which themselves use even larger components and libraries. I've updated my answer with the reported bug in bugzilla. you could help by starring it :) – vsync Jul 17 '16 at 12:01