在firefox中拖拽时,输入类型=range上的onchange事件没有触发

时间:2022-07-17 00:19:08

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.

当我使用时,只有当我们将滑块放置到新的位置时,Firefox才会触发onchange事件,而Chrome和其他浏览器会在拖拽滑块时触发onchange事件。

How can i make it happen on dragging in firefox?

我怎样才能在拖拽firefox时实现呢?

HTML

HTML

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

SCRIPT

脚本

function showVal(newVal){
  document.getElementById("valBox").innerHTML=newVal;
}

7 个解决方案

#1


350  

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:

但是,在IE10中不支持oninput,所以您最好将这两个事件处理程序结合在一起,如下所示:

<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 thread for more information.

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

#2


25  

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 answer elsewhere on this page that uses a different approach to providing a cross-browser desktop-and-mobile solution 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'…)的情况下读取范围输入值。和/或在(“变革”的…在浏览器之间不一致的工作。

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.

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

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事件,在所有浏览器中使用普通的JavaScript(即不使用jQuery)获得相同的连续范围值报告。

Strategy 1: Shorter but less efficient

策略一:更短但效率更低

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

策略二:更长但更有效

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&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>

#3


24  

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保存在一个独立的文件中。

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

请注意詹姆的评论

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.

在它中,当您停止移动鼠标时将触发事件,然后当您释放鼠标按钮时再次触发事件。

#4


20  

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跨浏览器桌面和移动功能,能够一致地响应范围/滑动条交互,这在当前浏览器中是不可能的。它本质上迫使所有浏览器模仿IE11的on(“change”…)为他们中的任何一方的事件(“改变”……)或(“输入”……事件。新功能是……

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月初,不同的浏览器在响应范围/滑块使用方面有不同。五个场景相关:

  1. initial mouse-down (or touch-start) at the current slider position
  2. 在当前滑块位置初始鼠标向下(或触摸启动)。
  3. initial mouse-down (or touch-start) at a new slider position
  4. 在一个新的滑块位置开始向下滑鼠(或触摸-开始)
  5. any subsequent mouse (or touch) movement after 1 or 2 along the slider
  6. 任何随后的鼠标(或触摸)在1或2之后沿滑块移动
  7. any subsequent mouse (or touch) movement after 1 or 2 past either end of the slider
  8. 在滑块两端1或2之后的任何后续鼠标(或触摸)移动
  9. final mouse-up (or touch-end)
  10. 最后鼠标释放(或touch-end)

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:

下表显示了至少三种不同的桌面浏览器在它们对上述场景中的哪一种做出反应时的行为有何不同:

在firefox中拖拽时,输入类型=range上的onchange事件没有触发

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函数为范围/滑动条交互提供一致和可预测的跨浏览器响应。强制所有浏览器按照下表执行:

在firefox中拖拽时,输入类型=range上的onchange事件没有触发

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中,代码本质上允许一切按现状运行,即允许“更改”事件以其标准方式运行,“输入”事件无关紧要,因为它永远不会触发。在其他浏览器中,“更改”事件被有效地屏蔽(以防止额外的、有时不是很明显的事件被触发)。此外,“输入”事件只在范围/滑块的值改变时触发侦听器。对于某些浏览器(例如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 page MBourne 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 desktop: IE, Chrome, Opera, FF;Android Chrome, Opera和FF, iOS Safari。(谢谢MBourne。)

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是您想要的 <输入类型="range"> DOM元素,myListener是您希望在“更改”类似事件中调用的侦听器/处理程序函数。

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:

如果需要,您的侦听器可以是无参数的,也可以使用事件参数,即根据您的需要,下列任何一种都可以工作:

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.)

(从输入元素中删除事件侦听器(例如,使用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提供了通用的解决方案。剩下的代码只是一个示例来演示它的使用。任何以…开始的变量。与通用解决方案无关,只是为了演示而存在。

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:

演示程序显示了范围/滑块值以及标准“更改”、“输入”和自定义“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.
  • 在IE11中,第A行和第C行中的值在上面的场景2和3中都会发生变化,而第B行则不会发生变化。
  • 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.
  • 在Chrome和Safari中,B和C行中的值都在场景2和3中发生变化,而A行仅在场景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.
  • 在Firefox中,第A行中的值仅在场景5中更改,第B行更改所有5个场景,第C行更改仅在场景2和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.
  • 在上述所有浏览器中,第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。

#5


4  

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、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).

谢谢,Andrew -这似乎适用于我能找到的所有浏览器(Win desktop: 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中再次起作用——可能还有其他冲突。

#6


0  

For a good cross-browser behavior, less and understandable code, best is to use the onchange attribute in combination of a form:

对于良好的跨浏览器行为,较少和可理解的代码,最好是结合使用onchange属性的表单:

This is a html/javascript only solution, and can as well be used in-line.

这是一个仅支持html/javascript的解决方案,也可以在线使用。

function showVal(){
 document.getElementById("valBox").innerHTML=document.getElementById("inVal").value;

}
<form onchange="showVal()">
  <input type="range" min="5" max="10" step="1" id="inVal">
  </form>

<span id="valBox">
  </span>

#7


-2  

You could use the JavaScript "ondrag" event to fire continuously. It is better than "input" due to the following reasons:

您可以使用JavaScript“ondrag”事件连续地触发。由于以下原因,它比“输入”要好:

  1. Browser support.

    浏览器的支持。

  2. 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

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

#1


350  

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:

但是,在IE10中不支持oninput,所以您最好将这两个事件处理程序结合在一起,如下所示:

<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 thread for more information.

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

#2


25  

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 answer elsewhere on this page that uses a different approach to providing a cross-browser desktop-and-mobile solution 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'…)的情况下读取范围输入值。和/或在(“变革”的…在浏览器之间不一致的工作。

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.

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

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事件,在所有浏览器中使用普通的JavaScript(即不使用jQuery)获得相同的连续范围值报告。

Strategy 1: Shorter but less efficient

策略一:更短但效率更低

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

策略二:更长但更有效

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&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>

#3


24  

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保存在一个独立的文件中。

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

请注意詹姆的评论

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.

在它中,当您停止移动鼠标时将触发事件,然后当您释放鼠标按钮时再次触发事件。

#4


20  

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跨浏览器桌面和移动功能,能够一致地响应范围/滑动条交互,这在当前浏览器中是不可能的。它本质上迫使所有浏览器模仿IE11的on(“change”…)为他们中的任何一方的事件(“改变”……)或(“输入”……事件。新功能是……

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月初,不同的浏览器在响应范围/滑块使用方面有不同。五个场景相关:

  1. initial mouse-down (or touch-start) at the current slider position
  2. 在当前滑块位置初始鼠标向下(或触摸启动)。
  3. initial mouse-down (or touch-start) at a new slider position
  4. 在一个新的滑块位置开始向下滑鼠(或触摸-开始)
  5. any subsequent mouse (or touch) movement after 1 or 2 along the slider
  6. 任何随后的鼠标(或触摸)在1或2之后沿滑块移动
  7. any subsequent mouse (or touch) movement after 1 or 2 past either end of the slider
  8. 在滑块两端1或2之后的任何后续鼠标(或触摸)移动
  9. final mouse-up (or touch-end)
  10. 最后鼠标释放(或touch-end)

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:

下表显示了至少三种不同的桌面浏览器在它们对上述场景中的哪一种做出反应时的行为有何不同:

在firefox中拖拽时,输入类型=range上的onchange事件没有触发

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函数为范围/滑动条交互提供一致和可预测的跨浏览器响应。强制所有浏览器按照下表执行:

在firefox中拖拽时,输入类型=range上的onchange事件没有触发

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中,代码本质上允许一切按现状运行,即允许“更改”事件以其标准方式运行,“输入”事件无关紧要,因为它永远不会触发。在其他浏览器中,“更改”事件被有效地屏蔽(以防止额外的、有时不是很明显的事件被触发)。此外,“输入”事件只在范围/滑块的值改变时触发侦听器。对于某些浏览器(例如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 page MBourne 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 desktop: IE, Chrome, Opera, FF;Android Chrome, Opera和FF, iOS Safari。(谢谢MBourne。)

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是您想要的 <输入类型="range"> DOM元素,myListener是您希望在“更改”类似事件中调用的侦听器/处理程序函数。

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:

如果需要,您的侦听器可以是无参数的,也可以使用事件参数,即根据您的需要,下列任何一种都可以工作:

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.)

(从输入元素中删除事件侦听器(例如,使用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提供了通用的解决方案。剩下的代码只是一个示例来演示它的使用。任何以…开始的变量。与通用解决方案无关,只是为了演示而存在。

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:

演示程序显示了范围/滑块值以及标准“更改”、“输入”和自定义“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.
  • 在IE11中,第A行和第C行中的值在上面的场景2和3中都会发生变化,而第B行则不会发生变化。
  • 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.
  • 在Chrome和Safari中,B和C行中的值都在场景2和3中发生变化,而A行仅在场景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.
  • 在Firefox中,第A行中的值仅在场景5中更改,第B行更改所有5个场景,第C行更改仅在场景2和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.
  • 在上述所有浏览器中,第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。

#5


4  

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、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).

谢谢,Andrew -这似乎适用于我能找到的所有浏览器(Win desktop: 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中再次起作用——可能还有其他冲突。

#6


0  

For a good cross-browser behavior, less and understandable code, best is to use the onchange attribute in combination of a form:

对于良好的跨浏览器行为,较少和可理解的代码,最好是结合使用onchange属性的表单:

This is a html/javascript only solution, and can as well be used in-line.

这是一个仅支持html/javascript的解决方案,也可以在线使用。

function showVal(){
 document.getElementById("valBox").innerHTML=document.getElementById("inVal").value;

}
<form onchange="showVal()">
  <input type="range" min="5" max="10" step="1" id="inVal">
  </form>

<span id="valBox">
  </span>

#7


-2  

You could use the JavaScript "ondrag" event to fire continuously. It is better than "input" due to the following reasons:

您可以使用JavaScript“ondrag”事件连续地触发。由于以下原因,它比“输入”要好:

  1. Browser support.

    浏览器的支持。

  2. 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

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