当我玩<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)”>


当前回答

更新:我把这个答案留在这里作为一个例子,如何使用鼠标事件在桌面(而不是移动)浏览器中使用范围/滑动条交互。然而,我现在在本页的其他地方写了一个完全不同的,我相信更好的答案,它使用不同的方法为这个问题提供一个跨浏览器的桌面和移动解决方案。

最初的回答:

概述:一个跨浏览器的纯JavaScript(即no-jQuery)解决方案,允许读取范围输入值,而无需使用on('input'…和/或在(“变革”的…在浏览器之间工作不一致。

截至今天(2016年2月下旬),浏览器仍然不一致,所以我在这里提供了一个新的解决方案。

问题:当使用范围输入时,即滑动条,on('input'…在Mac和Windows Firefox, Chrome和Opera以及Mac Safari中提供持续更新的范围值,而在('change'…仅在鼠标向上时报告范围值。相比之下,在Internet Explorer (v11)中,on('input'…根本不起作用,并且在('change'…不断更新。

我在这里报告两种策略,使用普通JavaScript(即没有jQuery),通过使用mousedown, mouemove和(可能的)mouseup事件,在所有浏览器中获得相同的连续范围值报告。

策略1:时间短但效率低

如果你喜欢更短的代码而不是更高效的代码,你可以使用第一种解决方案,它使用鼠标向下和鼠标移动,但不使用鼠标向上。这将根据需要读取滑块,但在任何鼠标悬停事件期间继续不必要地触发滑块,即使当用户没有单击并因此没有拖动滑块时也是如此。它本质上是在'mousedown'和'mousemove'事件之后读取范围值,使用requestAnimationFrame稍微延迟每个事件。

var rng = document.querySelector("input"); 读(“mousedown”); 读(“mousemove”); 读(“keydown”);//包含这个也允许键盘控制 函数读取(evtType) { rng。addEventListener(evtType, function() { 窗口。requestAnimationFrame(function () { document.querySelector (" div ")。innerHTML = rng.value; rng。setAttribute(“aria-valuenow rng.value);//包含可访问性 }); }); } 50 < div > < / div > < input type = "范围" / >

策略2:时间更长但效率更高

如果你需要更高效的代码,并且可以忍受更长的代码长度,那么你可以使用下面的解决方案,它使用mousedown, mouemove和mouseup。这也会根据需要读取滑块,但一旦释放鼠标按钮,就会适当地停止读取。本质上的区别是,它只在“mousedown”之后开始监听“mousemove”,而在“mouseup”之后停止监听“mousemove”。

var rng = document.querySelector("input"); var listener = function() { window.requestAnimationFrame(function() { document.querySelector("div").innerHTML = rng.value; }); }; rng.addEventListener("mousedown", function() { listener(); rng.addEventListener("mousemove", listener); }); rng.addEventListener("mouseup", function() { rng.removeEventListener("mousemove", listener); }); // include the following line to maintain accessibility // by allowing the listener to also be fired for // appropriate keyboard events rng.addEventListener("keydown", listener); <div>50</div><input type="range"/>

演示:对上述解决方案的需求和实现的更全面的解释

下面的代码更全面地演示了该策略的许多方面。演示中嵌入了解释:

var select, inp, listen, unlisten, anim, show, onInp, onChg, onDn1, onDn2, onMv1, onMv2, onUp, onMvCombo1, onDnCombo1, onUpCombo2, onMvCombo2, onDnCombo2; select = function(selctr) { return document.querySelector(selctr); }; inp = select("input"); listen = function(evtTyp, cb) { return inp. addEventListener(evtTyp, cb); }; unlisten = function(evtTyp, cb) { return inp.removeEventListener(evtTyp, cb); }; anim = function(cb) { return window.requestAnimationFrame(cb); }; show = function(id) { return function() { select("#" + id + " td~td~td" ).innerHTML = inp.value; select("#" + id + " td~td~td~td").innerHTML = (Math.random() * 1e20).toString(36); // random text }; }; onInp = show("inp" ) ; onChg = show("chg" ) ; onDn1 = show("mdn1") ; onDn2 = function() {anim(show("mdn2")); }; onMv1 = show("mmv1") ; onMv2 = function() {anim(show("mmv2")); }; onUp = show("mup" ) ; onMvCombo1 = function() {anim(show("cmb1")); }; onDnCombo1 = function() {anim(show("cmb1")); listen("mousemove", onMvCombo1);}; onUpCombo2 = function() { unlisten("mousemove", onMvCombo2);}; onMvCombo2 = function() {anim(show("cmb2")); }; onDnCombo2 = function() {anim(show("cmb2")); listen("mousemove", onMvCombo2);}; listen("input" , onInp ); listen("change" , onChg ); listen("mousedown", onDn1 ); listen("mousedown", onDn2 ); listen("mousemove", onMv1 ); listen("mousemove", onMv2 ); listen("mouseup" , onUp ); listen("mousedown", onDnCombo1); listen("mousedown", onDnCombo2); listen("mouseup" , onUpCombo2); table {border-collapse: collapse; font: 10pt Courier;} th, td {border: solid black 1px; padding: 0 0.5em;} input {margin: 2em;} li {padding-bottom: 1em;} <p>Click on 'Full page' to see the demonstration properly.</p> <table> <tr><th></th><th>event</th><th>range value</th><th>random update indicator</th></tr> <tr id="inp" ><td>A</td><td>input </td><td>100</td><td>-</td></tr> <tr id="chg" ><td>B</td><td>change </td><td>100</td><td>-</td></tr> <tr id="mdn1"><td>C</td><td>mousedown </td><td>100</td><td>-</td></tr> <tr id="mdn2"><td>D</td><td>mousedown using requestAnimationFrame</td><td>100</td><td>-</td></tr> <tr id="mmv1"><td>E</td><td>mousemove </td><td>100</td><td>-</td></tr> <tr id="mmv2"><td>F</td><td>mousemove using requestAnimationFrame</td><td>100</td><td>-</td></tr> <tr id="mup" ><td>G</td><td>mouseup </td><td>100</td><td>-</td></tr> <tr id="cmb1"><td>H</td><td>mousedown/move combo </td><td>100</td><td>-</td></tr> <tr id="cmb2"><td>I</td><td>mousedown/move/up combo </td><td>100</td><td>-</td></tr> </table> <input type="range" min="100" max="999" value="100"/> <ol> <li>The 'range value' column shows the value of the 'value' attribute of the range-type input, i.e. the slider. The 'random update indicator' column shows random text as an indicator of whether events are being actively fired and handled.</li> <li>To see browser differences between input and change event implementations, use the slider in different browsers and compare A and&nbsp;B.</li> <li>To see the importance of 'requestAnimationFrame' on 'mousedown', click a new location on the slider and compare C&nbsp;(incorrect) and D&nbsp;(correct).</li> <li>To see the importance of 'requestAnimationFrame' on 'mousemove', click and drag but do not release the slider, and compare E&nbsp;(often 1&nbsp;pixel behind) and F&nbsp;(correct).</li> <li>To see why an initial mousedown is required (i.e. to see why mousemove alone is insufficient), click and hold but do not drag the slider and compare E&nbsp;(incorrect), F&nbsp;(incorrect) and H&nbsp;(correct).</li> <li>To see how the mouse event combinations can provide a work-around for continuous update of a range-type input, use the slider in any manner and note whichever of A or B continuously updates the range value in your current browser. Then, while still using the slider, note that H and I provide the same continuously updated range value readings as A or B.</li> <li>To see how the mouseup event reduces unnecessary calculations in the work-around, use the slider in any manner and compare H and&nbsp;I. They both provide correct range value readings. However, then ensure the mouse is released (i.e. not clicked) and move it over the slider without clicking and notice the ongoing updates in the third table column for H but not&nbsp;I.</li> </ol>

其他回答

为了获得良好的跨浏览器行为和可理解的代码,最好是将onchange属性与表单结合使用:

函数showVal () { valBox。innerHTML = invalid .value; } <形式onchange = " showVal ()" > <input type="range" min="5" max="10" step="1" id="inVal"> > < /形式 < span id = " valBox " > < / span >

使用oninput也是一样,值是直接改变的。 函数showVal () { valBox。innerHTML = invalid .value; } <形式oninput = " showVal ()" > <input type="range" min="5" max="10" step="1" id="inVal"> > < /形式 < span id = " valBox " > < / span >

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

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

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

不过要注意Jaime的这句话

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

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

更新

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

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

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

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

I'm posting this as an answer in case you are like me and cannot figure out why the range type input doesn't work on ANY mobile browsers. If you develop mobile apps on your laptop and use the responsive mode to emulate touch, you will notice the range doesn't even move when you have the touch simulator activated. It starts moving when you deactivate it. I went on for 2 days trying every piece of code I could find on the subject and could not make it work for the life of me. I provide a WORKING solution in this post.

移动浏览器和混合应用

Mobile browsers run using a component called Webkit for iOS and WebView for Android. The WebView/WebKit enables you to embed a web browser, which does not have any chrome or firefox (browser) controls including window frames, menus, toolbars and scroll bars into your activity layout. In other words, mobile browsers lack a lot of web components normally found in regular browsers. This is the problem with the range type input. If the user's browser doesn't support range type, it will fall back and treat it as a text input. This is why you cannot move the range when the touch simulator is activated.

点击这里阅读更多关于浏览器兼容性的内容

jQuery滑块

jQuery提供了一个滑块,以某种方式与触摸模拟工作,但它是起伏的,不是很光滑。它不能满足我,它可能不会为你,但你可以使它工作更顺利,如果你结合jqueryUi。

最佳解决方案:范围触摸

如果你在笔记本电脑上开发混合应用程序,有一个简单易用的库可以让范围类型输入与触摸事件一起工作。

这个库叫做Range Touch。

DEMO

有关此问题的更多信息,请查看这里的这个线程

为移动Safari (webkit)重新创建HTML5范围输入?

显然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线程以获得更多信息。

更新:我把这个答案留在这里作为一个例子,如何使用鼠标事件在桌面(而不是移动)浏览器中使用范围/滑动条交互。然而,我现在在本页的其他地方写了一个完全不同的,我相信更好的答案,它使用不同的方法为这个问题提供一个跨浏览器的桌面和移动解决方案。

最初的回答:

概述:一个跨浏览器的纯JavaScript(即no-jQuery)解决方案,允许读取范围输入值,而无需使用on('input'…和/或在(“变革”的…在浏览器之间工作不一致。

截至今天(2016年2月下旬),浏览器仍然不一致,所以我在这里提供了一个新的解决方案。

问题:当使用范围输入时,即滑动条,on('input'…在Mac和Windows Firefox, Chrome和Opera以及Mac Safari中提供持续更新的范围值,而在('change'…仅在鼠标向上时报告范围值。相比之下,在Internet Explorer (v11)中,on('input'…根本不起作用,并且在('change'…不断更新。

我在这里报告两种策略,使用普通JavaScript(即没有jQuery),通过使用mousedown, mouemove和(可能的)mouseup事件,在所有浏览器中获得相同的连续范围值报告。

策略1:时间短但效率低

如果你喜欢更短的代码而不是更高效的代码,你可以使用第一种解决方案,它使用鼠标向下和鼠标移动,但不使用鼠标向上。这将根据需要读取滑块,但在任何鼠标悬停事件期间继续不必要地触发滑块,即使当用户没有单击并因此没有拖动滑块时也是如此。它本质上是在'mousedown'和'mousemove'事件之后读取范围值,使用requestAnimationFrame稍微延迟每个事件。

var rng = document.querySelector("input"); 读(“mousedown”); 读(“mousemove”); 读(“keydown”);//包含这个也允许键盘控制 函数读取(evtType) { rng。addEventListener(evtType, function() { 窗口。requestAnimationFrame(function () { document.querySelector (" div ")。innerHTML = rng.value; rng。setAttribute(“aria-valuenow rng.value);//包含可访问性 }); }); } 50 < div > < / div > < input type = "范围" / >

策略2:时间更长但效率更高

如果你需要更高效的代码,并且可以忍受更长的代码长度,那么你可以使用下面的解决方案,它使用mousedown, mouemove和mouseup。这也会根据需要读取滑块,但一旦释放鼠标按钮,就会适当地停止读取。本质上的区别是,它只在“mousedown”之后开始监听“mousemove”,而在“mouseup”之后停止监听“mousemove”。

var rng = document.querySelector("input"); var listener = function() { window.requestAnimationFrame(function() { document.querySelector("div").innerHTML = rng.value; }); }; rng.addEventListener("mousedown", function() { listener(); rng.addEventListener("mousemove", listener); }); rng.addEventListener("mouseup", function() { rng.removeEventListener("mousemove", listener); }); // include the following line to maintain accessibility // by allowing the listener to also be fired for // appropriate keyboard events rng.addEventListener("keydown", listener); <div>50</div><input type="range"/>

演示:对上述解决方案的需求和实现的更全面的解释

下面的代码更全面地演示了该策略的许多方面。演示中嵌入了解释:

var select, inp, listen, unlisten, anim, show, onInp, onChg, onDn1, onDn2, onMv1, onMv2, onUp, onMvCombo1, onDnCombo1, onUpCombo2, onMvCombo2, onDnCombo2; select = function(selctr) { return document.querySelector(selctr); }; inp = select("input"); listen = function(evtTyp, cb) { return inp. addEventListener(evtTyp, cb); }; unlisten = function(evtTyp, cb) { return inp.removeEventListener(evtTyp, cb); }; anim = function(cb) { return window.requestAnimationFrame(cb); }; show = function(id) { return function() { select("#" + id + " td~td~td" ).innerHTML = inp.value; select("#" + id + " td~td~td~td").innerHTML = (Math.random() * 1e20).toString(36); // random text }; }; onInp = show("inp" ) ; onChg = show("chg" ) ; onDn1 = show("mdn1") ; onDn2 = function() {anim(show("mdn2")); }; onMv1 = show("mmv1") ; onMv2 = function() {anim(show("mmv2")); }; onUp = show("mup" ) ; onMvCombo1 = function() {anim(show("cmb1")); }; onDnCombo1 = function() {anim(show("cmb1")); listen("mousemove", onMvCombo1);}; onUpCombo2 = function() { unlisten("mousemove", onMvCombo2);}; onMvCombo2 = function() {anim(show("cmb2")); }; onDnCombo2 = function() {anim(show("cmb2")); listen("mousemove", onMvCombo2);}; listen("input" , onInp ); listen("change" , onChg ); listen("mousedown", onDn1 ); listen("mousedown", onDn2 ); listen("mousemove", onMv1 ); listen("mousemove", onMv2 ); listen("mouseup" , onUp ); listen("mousedown", onDnCombo1); listen("mousedown", onDnCombo2); listen("mouseup" , onUpCombo2); table {border-collapse: collapse; font: 10pt Courier;} th, td {border: solid black 1px; padding: 0 0.5em;} input {margin: 2em;} li {padding-bottom: 1em;} <p>Click on 'Full page' to see the demonstration properly.</p> <table> <tr><th></th><th>event</th><th>range value</th><th>random update indicator</th></tr> <tr id="inp" ><td>A</td><td>input </td><td>100</td><td>-</td></tr> <tr id="chg" ><td>B</td><td>change </td><td>100</td><td>-</td></tr> <tr id="mdn1"><td>C</td><td>mousedown </td><td>100</td><td>-</td></tr> <tr id="mdn2"><td>D</td><td>mousedown using requestAnimationFrame</td><td>100</td><td>-</td></tr> <tr id="mmv1"><td>E</td><td>mousemove </td><td>100</td><td>-</td></tr> <tr id="mmv2"><td>F</td><td>mousemove using requestAnimationFrame</td><td>100</td><td>-</td></tr> <tr id="mup" ><td>G</td><td>mouseup </td><td>100</td><td>-</td></tr> <tr id="cmb1"><td>H</td><td>mousedown/move combo </td><td>100</td><td>-</td></tr> <tr id="cmb2"><td>I</td><td>mousedown/move/up combo </td><td>100</td><td>-</td></tr> </table> <input type="range" min="100" max="999" value="100"/> <ol> <li>The 'range value' column shows the value of the 'value' attribute of the range-type input, i.e. the slider. The 'random update indicator' column shows random text as an indicator of whether events are being actively fired and handled.</li> <li>To see browser differences between input and change event implementations, use the slider in different browsers and compare A and&nbsp;B.</li> <li>To see the importance of 'requestAnimationFrame' on 'mousedown', click a new location on the slider and compare C&nbsp;(incorrect) and D&nbsp;(correct).</li> <li>To see the importance of 'requestAnimationFrame' on 'mousemove', click and drag but do not release the slider, and compare E&nbsp;(often 1&nbsp;pixel behind) and F&nbsp;(correct).</li> <li>To see why an initial mousedown is required (i.e. to see why mousemove alone is insufficient), click and hold but do not drag the slider and compare E&nbsp;(incorrect), F&nbsp;(incorrect) and H&nbsp;(correct).</li> <li>To see how the mouse event combinations can provide a work-around for continuous update of a range-type input, use the slider in any manner and note whichever of A or B continuously updates the range value in your current browser. Then, while still using the slider, note that H and I provide the same continuously updated range value readings as A or B.</li> <li>To see how the mouseup event reduces unnecessary calculations in the work-around, use the slider in any manner and compare H and&nbsp;I. They both provide correct range value readings. However, then ensure the mouse is released (i.e. not clicked) and move it over the slider without clicking and notice the ongoing updates in the third table column for H but not&nbsp;I.</li> </ol>