当我玩的时候,只有当我们将滑块放到一个新的位置时,Firefox 才会触发 onchange 事件,Chrome 和其他人在拖动滑块时触发 onchange 事件。<input type="range">
如何在 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)">
显然Chrome和Safari是错误的:应该只在用户释放鼠标时触发。要获得持续更新,您应该使用该事件,该事件将从鼠标和键盘捕获Firefox,Safari和Chrome中的实时更新。onchange
oninput
但是,在 IE10 中不受支持,因此最好的办法是组合这两个事件处理程序,如下所示:oninput
<span id="valBox"></span>
<input
type="range"
min="5"
max="10"
step="1"
oninput="showVal(this.value)"
onchange="showVal(this.value)"
/>
查看此 Bugzilla 线程以获取更多信息。
总结:
我在这里提供了一个no-jQuery跨浏览器桌面和移动功能,以一致地响应范围/滑块交互,这在当前的浏览器中是不可能的。它基本上强制所有浏览器模拟IE11的事件,以用于其OR事件。新功能是…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 年 <> 月初,不同的浏览器在响应范围/滑块使用情况方面有所不同。有五种方案是相关的:
下表显示了至少三种不同的桌面浏览器在响应上述哪种方案方面的行为有何不同:
溶液:
该函数为范围/滑块交互提供一致且可预测的跨浏览器响应。它强制所有浏览器根据下表运行:onRangeChange
在IE11中,代码基本上允许一切按照现状运行,即它允许事件以标准方式运行,并且事件无关紧要,因为它永远不会触发。在其他浏览器中,事件被有效地静音(以防止触发额外的、有时不明显的事件)。此外,仅当范围/滑块的值更改时,事件才会触发其侦听器。对于某些浏览器(例如 Firefox),发生这种情况是因为侦听器在上述列表中的场景 1、4 和 5 中被有效地静音。"change"
"input"
"change"
"input"
(如果您确实需要在场景 1、4 和/或 5 中激活侦听器,您可以尝试合并“mousedown
”/“touchstart”、“
mousemove”/“touchmove
”和/或“mouseup
”/“touchend”
事件。这样的解决方案超出了本答案的范围。
移动浏览器中的功能:
我已经在桌面浏览器中测试了此代码,但没有在任何移动浏览器中测试过。但是,在此页面上的另一个答案中,MBourne已经表明我在这里的解决方案“……似乎可以在我能找到的每个浏览器中工作(Win桌面:IE,Chrome,Opera,FF;Android Chrome,Opera和FF,iOS Safari)”。(谢谢我。
用法:
要使用此解决方案,请在您自己的代码中包含上述摘要(简化/缩小)或下面的演示代码片段(功能相同但更不言自明)中的函数。按如下方式调用它:onRangeChange
onRangeChange(myRangeInputElmt, myListener);
其中是您想要的 DOM 元素,是您想要在类似事件时调用的侦听器/处理程序函数。myRangeInputElmt
<input type="range">
myListener
"change"
如果需要,您的侦听器可能是无参数的,或者可以使用该参数,即以下任一方法都可以工作,具体取决于您的需求:event
var myListener = function() {...
或
var myListener = function(evt) {...
(从输入
元素中删除事件侦听器(例如,使用 removeEventListener
)在本答案中未解决。
演示说明:
在下面的代码片段中,该函数提供了通用解决方案。代码的其余部分只是一个演示其用法的示例。任何以 开头的变量都与通用解决方案无关,并且只是为了演示而存在。onRangeChange
my...
该演示显示了范围/滑块值以及标准和自定义事件触发的次数(分别为 A、B 和 C 行)。在不同的浏览器中运行此代码段时,在与范围/滑块交互时请注意以下事项:"change"
"input"
"onRangeChange"
演示代码:
// 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 输入类型范围滑块事件更改输入浏览器兼容性跨浏览器桌面移动 no-jQuery
我将其作为答案发布,因为它应该成为它自己的答案,而不是在不太有用的答案下的评论。我发现这种方法比公认的答案要好得多,因为它可以将所有 js 保存在与 HTML 分开的文件中。
贾姆雷利安在接受的答案下的评论中提供的答案。
$("#myelement").on("input change", function() {
//do something
});
请注意Jaime的这个评论
请注意,使用此解决方案,在 chrome 中,您将获得对处理程序的两次调用(每个事件一次),因此,如果您关心这一点,那么您需要防范它。
就像它一样,当您停止移动鼠标时,它将触发事件,然后在释放鼠标按钮时再次触发事件。
关于事件和导致功能触发两次的事件,这几乎不是问题。change
input
如果函数在 上触发,则在事件触发时极不可能出现问题。input
change
input
拖动范围输入滑块时快速触发。担心最后再触发一个函数调用就像担心一滴水与事件的海洋相比。input
甚至包含事件的原因是为了浏览器兼容性(主要是与IE兼容)。change
模板简介:该模板名称为【 HTML 中 onchange 事件在 Firefox 中输入类型=范围在 Firefox 中拖动时未触发】,大小是暂无信息,文档格式为.编程语言,推荐使用Sublime/Dreamweaver/HBuilder打开,作品中的图片,文字等数据均可修改,图片请在作品中选中图片替换即可,文字修改直接点击文字修改即可,您也可以新增或修改作品中的内容,该模板来自用户分享,如有侵权行为请联系网站客服处理。欢迎来懒人模板【HTML】栏目查找您需要的精美模板。