当我玩<input type="range">时,Firefox只有在我们将滑块拖放到Chrome和其他滑块被拖动时触发onchange事件的新位置时才会触发onchange事件。

如何在Firefox中进行拖拽?

function showVal(newVal){ document.getElementById(“valBox”).innerHTML=newVal; } <span id=“valBox”></span> <输入类型=“范围” min=“5” max=“10” step=“1” onchange=“showVal(this.value)”>


当前回答

Andrew Willem的解决方案并不兼容移动设备。

以下是他的第二个解决方案的修改,适用于Edge、IE、Opera、FF、Chrome、iOS Safari和移动设备(我可以测试):

更新1:删除“requestAnimationFrame”部分,因为我同意这是不必要的。

var listener = function() {
  // do whatever
};

slider1.addEventListener("input", function() {
  listener();
  slider1.addEventListener("change", listener);
});
slider1.addEventListener("change", function() {
  listener();
  slider1.removeEventListener("input", listener);
}); 

更新2:对安德鲁2016年6月2日的更新答案的回应:

谢谢,安德鲁-这似乎在我能找到的每一个浏览器(Win桌面:IE, Chrome, Opera, FF;Android Chrome, Opera和FF, iOS Safari)。

更新3:if ("oninput in slider)解决方案

下面的代码似乎可以跨上述所有浏览器运行。(我现在找不到原始来源。)我在用这个,但后来在IE上失败了,所以我去找了一个不同的,因此我在这里结束了。

if ("oninput" in slider1) {
    slider1.addEventListener("input", function () {
        // do whatever;
    }, false);
}

但在我检查你的解决方案之前,我注意到这在IE中又工作了-也许有一些其他的冲突。

其他回答

显然Chrome和Safari是错误的:onchange应该只在用户释放鼠标时被触发。要获得持续更新,您应该使用oninput事件,它将从Firefox、Safari和Chrome中从鼠标和键盘捕获实时更新。

然而,在IE10中不支持oninput,所以你最好的办法是将两个事件处理程序结合起来,像这样:

<span id="valBox"></span>
<input
  type="range"
  min="5"
  max="10"
  step="1"
  oninput="showVal(this.value)"
  onchange="showVal(this.value)"
/>

查看Bugzilla线程以获得更多信息。

Andrew Willem的解决方案并不兼容移动设备。

以下是他的第二个解决方案的修改,适用于Edge、IE、Opera、FF、Chrome、iOS Safari和移动设备(我可以测试):

更新1:删除“requestAnimationFrame”部分,因为我同意这是不必要的。

var listener = function() {
  // do whatever
};

slider1.addEventListener("input", function() {
  listener();
  slider1.addEventListener("change", listener);
});
slider1.addEventListener("change", function() {
  listener();
  slider1.removeEventListener("input", listener);
}); 

更新2:对安德鲁2016年6月2日的更新答案的回应:

谢谢,安德鲁-这似乎在我能找到的每一个浏览器(Win桌面:IE, Chrome, Opera, FF;Android Chrome, Opera和FF, iOS Safari)。

更新3:if ("oninput in slider)解决方案

下面的代码似乎可以跨上述所有浏览器运行。(我现在找不到原始来源。)我在用这个,但后来在IE上失败了,所以我去找了一个不同的,因此我在这里结束了。

if ("oninput" in slider1) {
    slider1.addEventListener("input", function () {
        // do whatever;
    }, false);
}

但在我检查你的解决方案之前,我注意到这在IE中又工作了-也许有一些其他的冲突。

你可以使用JavaScript的"ondrag"事件来连续触发。它优于“输入”,原因如下:

浏览器的支持。 可以区分“ondrag”和“change”事件。“输入”触发拖拽和更改。

jQuery:

$('#sample').on('drag',function(e){

});

参考: http://www.w3schools.com/TAgs/ev_ondrag.asp

我把这个作为一个答案,因为它应该是它自己的答案,而不是一个不那么有用的答案下的评论。我发现这种方法比公认的答案要好得多,因为它可以将所有的js与HTML保存在一个单独的文件中。

由Jamrelian在他的评论中提供的答案。

$("#myelement").on("input change", function() {
    //do something
});

不过要注意Jaime的这句话

只是注意,有了这个解决方案,在chrome你会得到两个调用的处理程序(一个每个事件),所以如果你关心,那么你需要防范它。

它会在你停止移动鼠标时触发事件,然后在你释放鼠标按钮时再次触发事件。

更新

对于导致功能两次触发的更改事件和输入事件,这几乎不是问题。

如果函数在输入时触发,则在触发change事件时不太可能出现问题。

当你拖动范围输入滑块时,输入会迅速触发。担心最后再触发一个函数调用,就像担心输入事件中的一滴水。

甚至包括更改事件的原因是为了浏览器兼容性(主要是IE)。

还有另一种方法——在元素上设置一个标志,表明应该处理哪种类型的事件:

function setRangeValueChangeHandler(rangeElement, handler) {
    rangeElement.oninput = (event) => {
        handler(event);
        // Save flag that we are using onInput in current browser
        event.target.onInputHasBeenCalled = true;
    };

    rangeElement.onchange = (event) => {
        // Call only if we are not using onInput in current browser
        if (!event.target.onInputHasBeenCalled) {
            handler(event);
        }
    };
}