范围滑块输入事件未在 IE 10 中触发

Range slider input event not firing in IE 10

我有一个范围滑块,我想监听它的 changeinput 事件。这在大多数浏览器中工作正常,但在 IE 10 中,没有 input 事件触发,并且 changeinput 应该的那样一遍又一遍地触发。这是代码:

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');
  });

});

它在 codepen 上:http://codepen.io/ZevanRosser/pen/YPQVzJ

我想知道是否有解决此问题的方法 - polyfill 或一些简单的技巧。

所以我几天前想出了这个问题,并认为我会 post 我的解决方案。基本上,诀窍是检查您是否在 IE 中(使用您选择的嗅探方法)。然后劫持 range 输入的 change 事件并改为触发 input。然后,在 mouseup 上发射 change。到目前为止,这似乎很有效:

(这里有一支笔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();
  }

});

在我正在从事的项目中使用的实际版本中,我更改了一些内容。

  1. 该项目使用 lodash,因此应另一位开发人员的要求,我将 fireChange 事件部分化并将当前 range 输入作为第一个参数传递,而不是仅使用 currentSlider变量。这基本上是为了避免碰撞——很确定碰撞是不可能的,因为你一次只能滑动一个滑块,但我们认为安全总比抱歉好。

  2. 该项目已经有 IE 嗅探,所以我使用了已经存在的东西而不是你在这里看到的东西。

最好能以某种方式弄清楚此事件行为是否存在而不是嗅探 IE,但我无法完全弄清楚如何确定是否存在事件缺陷。

无论如何,希望对遇到此问题的其他人有所帮助。我认为还有一些改进的余地,但目前已经足够好了。

编辑:

正如 Justin Smith 在评论中提到的,IE10 不再支持条件注释。

Conditional comments are no longer supported

所以下面的代码在IE10下是正确的(我会去掉不好的评论),这个post不回复原答案

原文:

有了这段代码,你就可以用你的 ie 版本做你想做的事了:

如果您的浏览器不是 IE 版本之一,ie class 将不会在 html 标签上找到。此外,还将找到 ie class 以及 ieX 版本。

<!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]-->

及以下你有:

<input id="slider" type="range" />

之后,进入您的代码,只需执行以下操作:

  • 为所有浏览器触发 input
  • 为所有人开火change,即

所以

var html = document.getElementsByTagName("html")[0];
    slider = document.getElementById("slider"),
    input = (html.classList.contains("ie")) "change" : "input";

slider.addEventListener(input, function () {
    // Do something;
});

我找到了一个解决方案,我认为它比我迄今为止在该主题上看到的任何解决方案都要好,因为它不需要您检查您使用的是什么浏览器。

基本上不是检查输入,而是检查 mousedown,设置间隔,然后在 mouseup 上清除间隔。

var dragInterval = function dragInterval() {
        console.log(event);
    }, 10);
};

rangeInput.addEventListener('mousedown', function () {
    dragInterval();
});
rangeInput.addEventListener('mouseup', function () {
    clearInterval(dragInterval);
});