在Firefox浏览器中,拖动输入类型为range的元素时,其onchange事件不会被触发。

335

当我使用<input type="range">玩耍时,Firefox只会在将滑块拖动到新位置时触发onchange事件,而Chrome和其他浏览器则在拖动滑块时就会触发onchange事件。

如何使Firefox在拖动时也触发onchange事件?

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


5
如果滑块处于焦点状态,您可以使用箭头键移动滑块。在这种情况下,onchange 事件也不会触发。正是通过解决这个问题,我才找到了这个问题的答案。 - Sildoreth
10个回答

564

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


130
еҸҜд»ҘдҪҝз”ЁjQueryзҡ„$("#myelement").on("input change", function() { doSomething(); });жқҘе®һзҺ°гҖӮиҜҘд»Јз ҒдјҡеңЁе…ғзҙ еҸ‘з”ҹиҫ“е…ҘжҲ–еҸҳеҢ–ж—¶жү§иЎҢdoSomething()еҮҪж•°гҖӮ - TechAurelian
22
请注意,使用此解决方案在 Chrome 中将会触发两次事件处理程序调用(每个事件一次),因此如果您关心这一点,就需要对其进行保护。 - Jaime
3
我在使用移动版Chrome(v34)时遇到了“change”事件无法触发的问题,但将“input”加入方程式后,问题得到了解决,而且没有影响其他任何地方。 - brins0
7
如果你关心这件事,那么你需要防范它。请问我该如何做? - user648340
4
遗憾的是,移动网络上像Android Chrome和iOS Safari这样的浏览器不支持onchange()。有什么替代建议吗? - Alston
2
更新:在Chrome中,您可以使用“input”事件。 - Aditya

54

SUMMARY:

我在这里提供了一种没有使用jQuery的跨浏览器桌面和移动设备能够持续响应范围/滑块交互的方法,这在当前浏览器中是不可能做到的。它基本上强制所有浏览器模拟IE11的on("change"...事件来代替它们的on("change"...或者on("input"...事件。这个新函数是...

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

...其中r是您的范围输入元素,而f是您的监听器。该监听器将在任何更改范围/滑块值的交互之后调用,但不会在未更改该值的交互(包括在当前滑块位置处进行的初始鼠标或触摸交互,或在滑块的任一端移动时)之后调用。

问题:

截至2016年6月初,不同的浏览器在处理范围/滑块使用方面存在差异。涉及以下五种情况:

  1. 在当前滑块位置进行初始鼠标按下或触摸开始
  2. 在新滑块位置进行初始鼠标按下或触摸开始
  3. 在 1 或 2 之后沿着滑块进行的任何后续鼠标或触摸移动
  4. 在 1 或 2 之后通过滑块的任一端进行的任何后续鼠标或触摸移动
  5. 最终的鼠标弹起或触摸结束

以下表格显示了至少三个不同桌面浏览器在其响应上述场景中哪些方案方面存在差异:

table showing browser differences with respect to which events they respond to and when

解决方案:

onRangeChange 函数提供了跨浏览器对范围/滑块交互的一致和可预测的响应。它迫使所有浏览器都按照以下表格的方式进行操作:

table showing behaviour of all browsers using the proposed solution

在 IE11 中,该代码基本上允许一切像现状那样运作,即允许 "change" 事件按其标准方式工作,而 "input" 事件是无关紧要的,因为它永远不会触发。在其他浏览器中,"change" 事件实际上被静音(以防止额外的并且有时不容易察觉的事件触发)。此外,"input" 事件仅在范围/滑块的值更改时触发其监听器。对于某些浏览器(例如 Firefox),这是因为在上述列表中的情况 1、4 和 5 中,监听器被有效地静音。

(如果您确实需要在情况 1、4 和/或 5 中激活监听器,则可以尝试合并 "mousedown"/"touchstart""mousemove"/"touchmove" 和/或 "mouseup"/"touchend" 事件。这样的解决方案超出了本答案的范围。)

移动浏览器中的功能:

我已经在桌面浏览器中测试了这段代码,但没有在任何移动浏览器中进行测试。但是,在此页面的另一个答案中,MBourne表明我的解决方案在各种浏览器中都似乎可以运行(Win桌面:IE、Chrome、Opera、FF;Android Chrome、Opera和FF、iOS Safari)。 (谢谢MBourne。)

用法:

要使用此解决方案,请在您自己的代码中包含上述总结中的onRangeChange函数(简化/缩小),或包含下面的演示代码片段(功能上相同但更易理解)。按以下方式调用它:

onRangeChange(myRangeInputElmt, myListener);

其中 myRangeInputElmt 是你想要的 <input type="range"> DOM 元素,myListener 是你希望在类似于 "change" 的事件发生时调用的监听器/处理函数。

如果需要,你的监听器可以不带参数,也可以使用 event 参数。即以下任一方式都可根据你的需要使用:

var myListener = function() {...

或者
var myListener = function(evt) {...

(本答案不涉及从元素中移除事件侦听器(例如使用removeEventListener)的问题。)

Demo说明:

以下代码片段中,函数onRangeChange提供了通用解决方案。其余代码仅是为了演示它的使用而存在的示例。任何以my...开头的变量对于通用解决方案都无关紧要,仅出于演示目的而存在。

演示显示范围/滑块值以及标准的"change""input"和自定义的"onRangeChange"事件的触发次数(分别在A、B和C行)。在不同的浏览器中运行此片段时,请注意与范围/滑块交互时以下内容:

  • 在IE11中,在场景2和3中,行A和C中的值都会更改,而行B永远不会更改。
  • 在Chrome和Safari中,在情况2和3下,行B和C中的值都会更改,而行A仅在情况5下更改。
  • 在Firefox中,仅对于情况5,行A的值才会更改,行B在所有五种情况下均会更改,而行C仅在情况2和3下更改。
  • 在所有上述浏览器中,行C(建议的解决方案)的更改是相同的,即仅限于情况2和3。

Demo代码:

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

信用:虽然这里的实现大部分是我自己完成的,但灵感来自MBourne的答案。其他答案建议将“输入”和“更改”事件合并,并且生成的代码可以在桌面和移动浏览器中使用。然而,该答案中的代码会导致隐藏的“额外”事件被触发,本身就有问题,而且不同浏览器之间触发的事件也不同,这是另一个问题。我的实现解决了这些问题。 关键字:JavaScript输入类型范围滑块事件更改输入浏览器兼容性跨浏览器桌面移动无jQuery

1
为什么不在单个处理程序函数中禁用支持输入事件的浏览器的更改事件? - lost-and-found

42

我将其发布为答案,因为它应该是独立的答案,而不是在一个不太有用的答案下的评论。我发现这种方法比被接受的答案更好,因为它可以将所有js保留在与HTML分开的单独文件中。

Jamrelian 在被接受的答案下的评论中提供的答案。

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

请注意Jaime的评论:

请注意,使用这种解决方案,在chrome中您将会收到两次调用处理程序的通知(每个事件一次),所以如果您关心这个问题,那么您需要对此进行保护。

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

更新

关于change事件和input事件导致功能触发两次的问题,这几乎不是问题。

如果您的函数在input上触发,那么change事件触发时极不可能出现问题。

input在拖动范围输入滑块时会快速触发。担心最后还会触发一次函数调用,就像担心大海中的一滴水一样微不足道。

包含change事件的原因在于浏览器兼容性(主要针对IE)。


1
加1,这是唯一能在Internet Explorer上正常工作的解决方案!你也测试过其他浏览器了吗? - Jessica
2
这是jQuery,所以它不起作用的可能性非常低。我自己没有看到它在任何地方都不起作用。它甚至可以在移动设备上运行,这很棒。 - Daniel Tonon

35

更新:我将保留这个答案,作为如何在桌面浏览器中使用鼠标事件进行范围/滑块交互的示例(但不适用于移动设备)。然而,我现在已经在这个页面的其他地方写了一个完全不同的、我认为更好的答案,它使用一种不同的方法来提供跨浏览器的桌面和移动设备解决此问题的解决方案。

原始回答:

摘要:一种跨浏览器的纯JavaScript(即无需jQuery)解决方案,允许在不使用on('input'...和/或on('change'...的情况下读取范围输入值,这在各种浏览器之间工作不一致。

截至今天(2016年2月底),仍存在浏览器不一致性,因此我在这里提供了一个新的解决方法。

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

我在这里报告了两种使用原生 JavaScript(即无jQuery)的策略,以使用mousedown、mousemove和(可能)mouseup事件在所有浏览器中获得相同的连续范围值报告。

策略1:代码较短但效率较低

如果您更喜欢短的代码而不是效率更高的代码,可以使用这个第一解决方案,它使用mousedown和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"/>

策略二:较长但更高效

如果您需要更高效的代码且能容忍较长的代码长度,则可以使用以下解决方案,该方案使用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"/>

演示:对上述解决方法的需求和实现进行更详细的解释

以下代码更全面地展示了这种策略的许多方面。说明嵌入在演示中:

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>


非常好的信息。也许有时候可以添加触摸事件?touchmove 应该足够了,我认为在这种情况下它可以像 mousemove 一样处理。 - nick
@nick,请查看本页面上我的另一个答案,其中提供了可以提供移动浏览器功能的不同解决方案。 - Andrew Willems
1
这不是一个可访问的答案,因为键盘导航不会触发所有基于鼠标的事件。 - LocalPCGuy
@LocalPCGuy,你说得对。我的答案破坏了滑块的内置键盘可控性。我已经更新了代码以恢复键盘控制。如果你知道我的代码破坏了其他内置辅助功能的方式,请告诉我。 - Andrew Willems

7

安德鲁·威廉的解决方案不兼容移动设备。

以下是他第二个解决方案的修改版,适用于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:"oninput in slider"解决方案 以下内容似乎适用于上述所有浏览器。(我现在找不到原始来源了。)我曾经使用过这个,但后来在IE上失败了,所以我去寻找了另一个,因此我来到了这里。
if ("oninput" in slider1) {
    slider1.addEventListener("input", function () {
        // do whatever;
    }, false);
}

但在我检查您的解决方案之前,我注意到在IE中此问题已经得到了解决 - 可能存在其他冲突。


2
我确认你的解决方案在两个不同的桌面浏览器上都能正常工作:Mac Firefox和Windows IE11。我个人还没有能够检查任何移动设备的可能性。但这看起来像是对我的答案的一个很好的更新,它扩大了它的适用范围,包括移动设备。(我假设“输入”和“更改”在桌面系统上接受鼠标输入,在移动系统上接受触摸输入。)非常好的工作,应该广泛适用,并值得获得认可和实施! - Andrew Willems
1
经过进一步的研究,我意识到您的解决方案存在几个缺点。首先,我认为requestAnimationFrame是不必要的。其次,该代码会触发额外的事件(例如,在某些浏览器中,mouseup至少会触发3个事件)。第三,不同浏览器之间触发的确切事件不同。因此,我提供了一个单独的答案,基于您最初使用“input”和“change”事件的想法,并给予您原始灵感的荣誉。 - Andrew Willems

5

为了获得良好的跨浏览器行为和易于理解的代码,最好结合表单使用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.

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>


2
我将此作为答案发布,以防您像我一样无法弄清楚为什么范围类型输入在任何移动浏览器上都不起作用。如果您在笔记本电脑上开发移动应用程序并使用响应模式来模拟触摸,则会注意到当您激活触摸模拟器时,范围根本不会移动。只有在停用它后才开始移动。我试了两天,尝试了我能找到的所有相关代码,但始终无法使其正常工作。在这篇文章中,我提供了一个可行的解决方案。
移动浏览器和混合应用程序
移动浏览器使用称为Webkit for iOSWebView for Android的组件运行。 WebView / WebKit使您能够嵌入Web浏览器,该浏览器没有任何Chrome或Firefox(浏览器)控件,包括窗口框架,菜单,工具栏和滚动条,可以将其嵌入到您的活动布局中。换句话说,移动浏览器缺少许多通常在常规浏览器中找到的Web组件。这就是范围类型输入的问题所在。如果用户的浏览器不支持范围类型,则会回退并将其视为文本输入。这就是为什么您无法在激活触摸模拟器时移动范围的原因。

jQuery 滑块

jQuery 提供了一个滑块,它可以通过触摸模拟工作,但是它很卡顿,不太流畅。这对我来说并不令人满意,对你来说也可能不会,但是如果你将其与 jqueryUi 结合使用,可以使其更加流畅。

最佳解决方案:Range Touch

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

该库称为Range Touch

演示

有关此问题的更多信息,请查看此处的线程。

请在浏览器兼容性中阅读更多信息。
重新创建 HTML5 范围输入以适用于移动 Safari (WebKit)?

这对于触摸系统的触感和平滑移动非常有好处。但是对于onchange事件没有任何解决方案。 - ehsan wwe

1
另一种方法是在元素上设置一个标志,表示应处理哪种类型的事件:
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);
        }
    };
}

-2

在React-Bootstrap中,这对我很有帮助

           <Form.Control
              type="range"
              className="slider"
              min="0.1"
              max="10"
              step={0.1}
              value={intensity}
              onChange={(e: any) => {
                if (!e.target.onInputHasBeenCalled) {
                  setIntensity(parseFloat(e.target.value.toString()));
                  e.target.onInputHasBeenCalled = true;
                } else {
                  e.target.onInputHasBeenCalled = false;
                }
              }}
            />

-4
你可以使用JavaScript的“ondrag”事件来连续触发。它比“input”更好,原因如下:
  1. 浏览器支持。

  2. 可以区分“ondrag”和“change”事件。“input”对于拖动和更改都会触发。

在jQuery中:

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

});

Reference: http://www.w3schools.com/TAgs/ev_ondrag.asp


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接