Html 拖动时输入类型 = 范围的 onchange 事件未在 Firefox 中触发
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18544890/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
onchange event on input type=range is not triggering in firefox while dragging
提问by Prasanth K C
When I played with <input type="range">
, Firefox triggers an onchange event only if we drop the slider to a new position where Chrome and others triggers onchange events while the slider is dragged.
当我使用 时<input type="range">
,仅当我们将滑块放到一个新位置时,Firefox 才会触发 onchange 事件,在该位置 Chrome 和其他人在拖动滑块时会触发 onchange 事件。
How can I make it happen on dragging in Firefox?
我怎样才能让它在 Firefox 中拖动时发生?
function showVal(newVal){
document.getElementById("valBox").innerHTML=newVal;
}
<span id="valBox"></span>
<input type="range" min="5" max="10" step="1" onchange="showVal(this.value)">
回答by Frederik
Apparently Chrome and Safari are wrong: onchange
should only be triggered when the user releases the mouse. To get continuous updates, you should use the oninput
event, which will capture live updates in Firefox, Safari and Chrome, both from the mouse and the keyboard.
显然 Chrome 和 Safari 是错误的:onchange
应该只在用户释放鼠标时触发。要获得持续更新,您应该使用该oninput
事件,该事件将通过鼠标和键盘在 Firefox、Safari 和 Chrome 中捕获实时更新。
However, oninput
is not supported in IE10, so your best bet is to combine the two event handlers, like this:
但是,oninput
在 IE10 中不支持,所以最好的办法是组合两个事件处理程序,如下所示:
<span id="valBox"></span>
<input type="range" min="5" max="10" step="1"
oninput="showVal(this.value)" onchange="showVal(this.value)">
Check out this Bugzilla threadfor more information.
查看此Bugzilla 线程以获取更多信息。
回答by Andrew Willems
SUMMARY:
概括:
I provide here a no-jQuery cross-browser desktop-and-mobile ability to consistently respond to range/slider interactions, something not possible in current browsers. It essentially forces all browsers to emulate IE11's on("change"...
event for either their on("change"...
or on("input"...
events. The new function is...
我在这里提供了一种非 jQuery 跨浏览器桌面和移动设备的能力,可以一致地响应范围/滑块交互,这在当前浏览器中是不可能的。它实质上强制所有浏览器on("change"...
为其on("change"...
或on("input"...
事件模拟 IE11 的事件。新功能是...
function onRangeChange(r,f) {
var n,c,m;
r.addEventListener("input",function(e){n=1;c=e.target.value;if(c!=m)f(e);m=c;});
r.addEventListener("change",function(e){if(!n)f(e);});
}
...where r
is your range input element and f
is your listener. The listener will be called after any interaction that changes the range/slider value but not after interactions that do not change that value, including initial mouse or touch interactions at the current slider position or upon moving off either end of the slider.
...r
你的范围输入元素在哪里,f
你的听众在哪里。侦听器将在任何更改范围/滑块值的交互之后调用,但不会在不更改该值的交互之后调用,包括在当前滑块位置处的初始鼠标或触摸交互或从滑块的任一端移开时。
Problem:
问题:
As of early June 2016, different browsers differ in terms of how they respond to range/slider usage. Five scenarios are relevant:
截至 2016 年 6 月上旬,不同浏览器对范围/滑块使用的响应方式有所不同。五个场景相关:
- initial mouse-down (or touch-start) at the current slider position
- initial mouse-down (or touch-start) at a new slider position
- any subsequent mouse (or touch) movement after 1 or 2 along the slider
- any subsequent mouse (or touch) movement after 1 or 2 past either end of the slider
- final mouse-up (or touch-end)
- 当前滑块位置的初始鼠标按下(或触摸启动)
- 在新的滑块位置初始鼠标按下(或触摸启动)
- 沿滑块 1 或 2 之后的任何后续鼠标(或触摸)移动
- 在经过滑块任一端 1 或 2 次之后的任何后续鼠标(或触摸)移动
- 最终鼠标向上(或触摸结束)
The following table shows how at least three different desktop browsers differ in their behaviour with respect to which of the above scenarios they respond to:
下表显示了至少三种不同的桌面浏览器在响应上述哪种场景方面的行为不同:
Solution:
解决方案:
The onRangeChange
function provides a consistent and predictable cross-browser response to range/slider interactions. It forces all browsers to behave according to the following table:
该onRangeChange
函数为范围/滑块交互提供一致且可预测的跨浏览器响应。它强制所有浏览器按照下表进行操作:
In IE11, the code essentially allows everything to operate as per the status quo, i.e. it allows the "change"
event to function in its standard way and the "input"
event is irrelevant as it never fires anyway. In other browsers, the "change"
event is effectively silenced (to prevent extra and sometimes not-readily-apparent events from firing). In addition, the "input"
event fires its listener only when the range/slider's value changes. For some browsers (e.g. Firefox) this occurs because the listener is effectively silenced in scenarios 1, 4 and 5 from the above list.
在 IE11 中,代码基本上允许一切按照现状运行,即它允许"change"
事件以其标准方式运行,并且"input"
事件无关紧要,因为它无论如何都不会触发。在其他浏览器中,该"change"
事件被有效地静音(以防止触发额外的、有时不明显的事件)。此外,"input"
仅当范围/滑块的值发生变化时,事件才会触发其侦听器。对于某些浏览器(例如 Firefox),发生这种情况是因为在上述列表中的场景 1、4 和 5 中侦听器被有效地静音。
(If you truly require a listener to be activated in either scenario 1, 4 and/or 5 you could try incorporating "mousedown"
/"touchstart"
, "mousemove"
/"touchmove"
and/or "mouseup"
/"touchend"
events. Such a solution is beyond the scope of this answer.)
(如果您确实需要在场景 1、4 和/或 5 中激活侦听器,您可以尝试合并"mousedown"
/ "touchstart"
、"mousemove"
/"touchmove"
和/或"mouseup"
/"touchend"
事件。这样的解决方案超出了本答案的范围。)
Functionality in Mobile Browsers:
移动浏览器中的功能:
I have tested this code in desktop browsers but not in any mobile browsers. However, in another answer on this pageMBourne has shown that my solution here "...appears to work in every browser I could find (Win desktop: IE, Chrome, Opera, FF; Android Chrome, Opera and FF, iOS Safari)". (Thanks MBourne.)
我已经在桌面浏览器中测试过这段代码,但没有在任何移动浏览器中测试过。但是,在本页的另一个答案中,MBourne 表明我的解决方案“...似乎适用于我能找到的每个浏览器(Win 桌面:IE、Chrome、Opera、FF;Android Chrome、Opera 和 FF、iOS Safari) ”。(感谢姆伯恩。)
Usage:
用法:
To use this solution, include the onRangeChange
function from the summary above (simplified/minified) or the demo code snippet below (functionally identical but more self-explanatory) in your own code. Invoke it as follows:
要使用此解决方案,请onRangeChange
在您自己的代码中包含以上摘要(简化/缩小)中的函数或以下演示代码片段(功能相同但更不言自明)。调用它如下:
onRangeChange(myRangeInputElmt, myListener);
where myRangeInputElmt
is your desired <input type="range">
DOM element and myListener
is the listener/handler function you want invoked upon "change"
-like events.
myRangeInputElmt
您想要的<input type="range">
DOM 元素在哪里,以及myListener
您想要在"change"
类似事件上调用的侦听器/处理程序函数在哪里。
Your listener may be parameter-less if desired or may use the event
parameter, i.e. either of the following would work, depending on your needs:
如果需要,您的侦听器可以是无参数的,也可以使用该event
参数,即根据您的需要,以下任一方法都可以工作:
var myListener = function() {...
or
或者
var myListener = function(evt) {...
(Removing the event listener from the input
element (e.g. using removeEventListener
) is not addressed in this answer.)
(从input
元素中删除事件侦听器(例如使用removeEventListener
)在这个答案中没有解决。)
Demo Description:
演示说明:
In the code snippet below, the function onRangeChange
provides the universal solution. The rest of the code is simply an example to demonstrate its use. Any variable that begins with my...
is irrelevant to the universal solution and is only present for the sake of the demo.
在下面的代码片段中,该函数onRangeChange
提供了通用解决方案。其余代码只是演示其使用的示例。任何以 开头的变量my...
都与通用解决方案无关,只是为了演示而存在。
The demo shows the range/slider value as well as the number of times the standard "change"
, "input"
and custom "onRangeChange"
events have fired (rows A, B and C respectively). When running this snippet in different browsers, note the following as you interact with the range/slider:
演示显示的范围内/滑块值以及次标准数"change"
,"input"
和自定义"onRangeChange"
事件烧制(行分别为A,B和C)。在不同浏览器中运行此代码段时,请注意与范围/滑块交互时的以下内容:
- In IE11, the values in rows A and C both change in scenarios 2 and 3 above while row B never changes.
- In Chrome and Safari, the values in rows B and C both change in scenarios 2 and 3 while row A changes only for scenario 5.
- In Firefox, the value in row A changes only for scenario 5, row B changes for all five scenarios, and row C changes only for scenarios 2 and 3.
- In all of the above browsers, the changes in row C (the proposed solution) are identical, i.e. only for scenarios 2 and 3.
- 在 IE11 中,A 行和 C 行中的值在上面的场景 2 和 3 中都发生了变化,而 B 行从未发生变化。
- 在 Chrome 和 Safari 中,B 行和 C 行中的值在场景 2 和 3 中都发生了变化,而 A 行中的值仅在场景 5 中发生了变化。
- 在 Firefox 中,A 行中的值仅在场景 5 中发生变化,B 行中所有五个场景都发生变化,C 行中仅在场景 2 和 3 中发生变化。
- 在上述所有浏览器中,C 行(建议的解决方案)中的变化是相同的,即仅针对场景 2 和 3。
Demo Code:
演示代码:
// main function for emulating IE11's "change" event:
function onRangeChange(rangeInputElmt, listener) {
var inputEvtHasNeverFired = true;
var rangeValue = {current: undefined, mostRecent: undefined};
rangeInputElmt.addEventListener("input", function(evt) {
inputEvtHasNeverFired = false;
rangeValue.current = evt.target.value;
if (rangeValue.current !== rangeValue.mostRecent) {
listener(evt);
}
rangeValue.mostRecent = rangeValue.current;
});
rangeInputElmt.addEventListener("change", function(evt) {
if (inputEvtHasNeverFired) {
listener(evt);
}
});
}
// example usage:
var myRangeInputElmt = document.querySelector("input" );
var myRangeValPar = document.querySelector("#rangeValPar" );
var myNumChgEvtsCell = document.querySelector("#numChgEvtsCell");
var myNumInpEvtsCell = document.querySelector("#numInpEvtsCell");
var myNumCusEvtsCell = document.querySelector("#numCusEvtsCell");
var myNumEvts = {input: 0, change: 0, custom: 0};
var myUpdate = function() {
myNumChgEvtsCell.innerHTML = myNumEvts["change"];
myNumInpEvtsCell.innerHTML = myNumEvts["input" ];
myNumCusEvtsCell.innerHTML = myNumEvts["custom"];
};
["input", "change"].forEach(function(myEvtType) {
myRangeInputElmt.addEventListener(myEvtType, function() {
myNumEvts[myEvtType] += 1;
myUpdate();
});
});
var myListener = function(myEvt) {
myNumEvts["custom"] += 1;
myRangeValPar.innerHTML = "range value: " + myEvt.target.value;
myUpdate();
};
onRangeChange(myRangeInputElmt, myListener);
table {
border-collapse: collapse;
}
th, td {
text-align: left;
border: solid black 1px;
padding: 5px 15px;
}
<input type="range"/>
<p id="rangeValPar">range value: 50</p>
<table>
<tr><th>row</th><th>event type </th><th>number of events </th><tr>
<tr><td>A</td><td>standard "change" events </td><td id="numChgEvtsCell">0</td></tr>
<tr><td>B</td><td>standard "input" events </td><td id="numInpEvtsCell">0</td></tr>
<tr><td>C</td><td>new custom "onRangeChange" events</td><td id="numCusEvtsCell">0</td></tr>
</table>
Credit:
信用:
While the implementation here is largely my own, it was inspired by MBourne's answer. That other answer suggested that the "input" and "change" events could be merged and that the resulting code would work in both desktop and mobile browsers. However, the code in that answer results in hidden "extra" events being fired, which in and of itself is problematic, and the events fired differ between browsers, a further problem. My implementation here solves those problems.
虽然这里的实现主要是我自己的,但它的灵感来自MBourne 的回答。另一个答案表明可以合并“输入”和“更改”事件,并且生成的代码可以在桌面和移动浏览器中使用。但是,该答案中的代码导致隐藏的“额外”事件被触发,这本身就是有问题的,并且触发的事件在浏览器之间有所不同,这是另一个问题。我在这里的实现解决了这些问题。
Keywords:
关键词:
JavaScript input type range slider events change input browser compatability cross-browser desktop mobile no-jQuery
JavaScript 输入类型范围滑块事件更改输入浏览器兼容性跨浏览器桌面移动无jQuery
回答by Daniel Tonon
I'm posting this as an answer because it deserves to be it's own answer rather than a comment under a less useful answer. I find this method much better than the accepted answer since it can keep all the js in a separate file from the HTML.
我将此作为答案发布,因为它应该是它自己的答案,而不是在不太有用的答案下发表评论。我发现这种方法比接受的答案要好得多,因为它可以将所有 js 保存在与 HTML 不同的文件中。
Answer provided by Jamrelian in his comment under the accepted answer.
Jamrelian 在接受的答案下的评论中提供的答案。
$("#myelement").on("input change", function() {
//do something
});
Just be aware of this comment by Jaime though
请注意 Jaime 的这条评论
Just note that with this solution, in chrome you will get two calls to the handler (one per event), so if you care for that, then you need to guard against it.
请注意,使用此解决方案,在 chrome 中,您将收到两次对处理程序的调用(每个事件一次),因此如果您关心这一点,则需要防范它。
As in it will fire the event when you have stopped moving the mouse, and then again when you release the mouse button.
因为它会在您停止移动鼠标时触发该事件,然后在您释放鼠标按钮时再次触发该事件。
Update
更新
In relation to the change
event and input
event causing the functionality to trigger twice, this is pretty much a non-issue.
对于导致功能触发两次的change
事件和input
事件,这几乎不是问题。
If you have a function firing off on input
, it is extremely unlikely that there will be a problem when the change
event fires.
如果您有一个函数触发 on input
,则在change
事件触发时极不可能出现问题。
input
fires rapidly as you drag a range input slider. Worrying about one more function call firing at the end is like worrying about a single drop of water compared to the ocean of water that is the input
events.
input
当您拖动范围输入滑块时会快速触发。与作为input
事件的海洋相比,担心最后再触发一个函数调用就像担心一滴水。
The reason for even including the change
event at all is for the sake of browser compatibility (mainly with IE).
甚至包括change
事件的原因是为了浏览器兼容性(主要是与 IE)。
回答by Andrew Willems
UPDATE: I am leaving this answer here as an example of how to use mouse events to use range/slider interactions in desktop (but not mobile) browsers. However, I have now also written a completely different and, I believe, better answerelsewhere on this page that uses a different approach to providing a cross-browser desktop-and-mobilesolution to this problem.
更新:我将这个答案留在这里作为如何使用鼠标事件在桌面(但不是移动)浏览器中使用范围/滑块交互的示例。但是,我现在还写了一个完全不同的,我相信,在本页其他地方的更好的答案,它使用不同的方法为这个问题提供跨浏览器的桌面和移动解决方案。
Original answer:
原答案:
Summary: A cross-browser, plain JavaScript (i.e. no-jQuery) solution to allow reading range input values without using on('input'...
and/or on('change'...
which work inconsistently between browsers.
简介: 一种跨浏览器的纯 JavaScript(即无 jQuery)解决方案,允许在不使用on('input'...
和/或on('change'...
在浏览器之间不一致的情况下读取范围输入值。
As of today (late Feb, 2016), there is still browser inconsistency so I'm providing a new work-around here.
截至今天(2016 年 2 月下旬),仍然存在浏览器不一致的问题,因此我在这里提供了一个新的解决方法。
The problem: When using a range input, i.e. a slider, on('input'...
provides continuously updated range values in Mac and Windows Firefox, Chrome and Opera as well as Mac Safari, while on('change'...
only reports the range value upon mouse-up. In contrast, in Internet Explorer (v11), on('input'...
does not work at all, and on('change'...
is continuously updated.
问题:当使用范围输入时,即滑块,on('input'...
在 Mac 和 Windows Firefox、Chrome 和 Opera 以及 Mac Safari 中提供持续更新的范围值,而on('change'...
仅在鼠标抬起时报告范围值。相比之下,在 Internet Explorer (v11) 中,on('input'...
根本不起作用,并且on('change'...
会不断更新。
I report here 2 strategies to get identical continuous range value reporting in all browsers using vanilla JavaScript (i.e. no jQuery) by using the mousedown, mousemove and (possibly) mouseup events.
我在这里报告了两种策略,通过使用 mousedown、mousemove 和(可能)mouseup 事件,在所有使用 vanilla JavaScript(即没有 jQuery)的浏览器中获得相同的连续范围值报告。
Strategy 1: Shorter but less efficient
策略 1:更短但效率更低
If you prefer shorter code over more efficient code, you can use this 1st solution which uses mousesdown and mousemove but not mouseup. This reads the slider as needed, but continues firing unnecessarily during any mouse-over events, even when the user has not clicked and is thus not dragging the slider. It essentially reads the range value both after 'mousedown' and during 'mousemove' events, slightly delaying each using requestAnimationFrame
.
如果您更喜欢更短的代码而不是更高效的代码,您可以使用第一个解决方案,它使用 mousesdown 和 mousemove 但不使用 mouseup。这会根据需要读取滑块,但在任何鼠标悬停事件期间会继续不必要地触发,即使用户没有单击并因此没有拖动滑块。它本质上在 'mousedown' 和 'mousemove' 事件期间读取范围值,使用requestAnimationFrame
.
var rng = document.querySelector("input");
read("mousedown");
read("mousemove");
read("keydown"); // include this to also allow keyboard control
function read(evtType) {
rng.addEventListener(evtType, function() {
window.requestAnimationFrame(function () {
document.querySelector("div").innerHTML = rng.value;
rng.setAttribute("aria-valuenow", rng.value); // include for accessibility
});
});
}
<div>50</div><input type="range"/>
Strategy 2: Longer but more efficient
策略 2:更长但更有效
If you need more efficient code and can tolerate longer code length, then you can use the following solution which uses mousedown, mousemove and mouseup. This also reads the slider as needed, but appropriately stops reading it as soon as the mouse button is released. The essential difference is that is only starts listening for 'mousemove' after 'mousedown', and it stops listening for 'mousemove' after 'mouseup'.
如果您需要更高效的代码并且可以容忍更长的代码长度,那么您可以使用以下使用 mousedown、mousemove 和 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"/>
Demo: Fuller explanation of the need for, and implementation of, the above work-arounds
演示:对上述变通方法的必要性和实施的更全面解释
The following code more fully demonstrates numerous aspects of this strategy. Explanations are embedded in the demonstration:
以下代码更全面地展示了该策略的许多方面。演示中嵌入了说明:
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 B.</li>
<li>To see the importance of 'requestAnimationFrame' on 'mousedown', click a new location on the slider and compare C (incorrect) and D (correct).</li>
<li>To see the importance of 'requestAnimationFrame' on 'mousemove', click and drag but do not release the slider, and compare E (often 1 pixel behind) and F (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 (incorrect), F (incorrect) and H (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 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 I.</li>
</ol>
回答by MBourne
Andrew Willem's solutions are not mobile device compatible.
Andrew Willem 的解决方案与移动设备不兼容。
Here's a modification of his second solution that works in Edge, IE, Opera, FF, Chrome, iOS Safari and mobile equivalents (that I could test):
这是他的第二个解决方案的修改,适用于 Edge、IE、Opera、FF、Chrome、iOS Safari 和移动等价物(我可以测试):
Update 1: Removed "requestAnimationFrame" portion, as I agree it's not necessary:
更新 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);
});
Update 2: Response to Andrew's 2nd Jun 2016 updated answer:
更新 2:对安德鲁 2016 年 6 月 2 日更新答案的回应:
Thanks, Andrew - that appears to work in every browser I could find (Win desktop: IE, Chrome, Opera, FF; Android Chrome, Opera and FF, iOS Safari).
谢谢,安德鲁 - 这似乎适用于我能找到的所有浏览器(Win 桌面:IE、Chrome、Opera、FF;Android Chrome、Opera 和 FF、iOS Safari)。
Update 3: if ("oninput in slider) solution
更新 3: if ("oninput in slider) 解决方案
The following appears to work across all the above browsers. (I cannot find the original source now.) I was using this, but it subsequently failed on IE and so I went looking for a different one, hence I ended up here.
以下似乎适用于所有上述浏览器。(我现在找不到原始来源。)我正在使用它,但它随后在 IE 上失败了,所以我去寻找一个不同的,因此我结束了这里。
if ("oninput" in slider1) {
slider1.addEventListener("input", function () {
// do whatever;
}, false);
}
But before I checked your solution, I noticed this was working again in IE - perhaps there was some other conflict.
但是在我检查您的解决方案之前,我注意到这在 IE 中再次起作用 - 也许还有其他一些冲突。
回答by NVRM
For a good cross-browser behavior, and understandable code, best is to use the onchange attribute in combination of a form:
对于良好的跨浏览器行为和可理解的代码,最好是结合表单使用 onchange 属性:
function showVal(){
valBox.innerHTML = inVal.value;
}
<form onchange="showVal()">
<input type="range" min="5" max="10" step="1" id="inVal">
</form>
<span id="valBox">
</span>
The same using oninput, the value is changed directly.
同样使用oninput,直接改变值。
function showVal(){
valBox.innerHTML = inVal.value;
}
<form oninput="showVal()">
<input type="range" min="5" max="10" step="1" id="inVal">
</form>
<span id="valBox">
</span>
回答by Nikita
Yet another approach - just set a flag on an element signaling which type of event should be handled:
另一种方法 - 只需在元素上设置一个标志,表明应该处理哪种类型的事件:
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);
}
};
}
回答by Sheik
You could use the JavaScript "ondrag" event to fire continuously. It is better than "input" due to the following reasons:
您可以使用 JavaScript "ondrag" 事件连续触发。由于以下原因,它比“输入”更好:
Browser support.
Could differentiate between "ondrag" and "change" event. "input" fires for both drag and change.
浏览器支持。
可以区分“ondrag”和“change”事件。“输入”触发拖动和更改。
In jQuery:
在 jQuery 中:
$('#sample').on('drag',function(e){
});
Reference: http://www.w3schools.com/TAgs/ev_ondrag.asp