是否可以禁用滚轮在输入数字字段中更改数字?我已经弄乱了特定于Webkit的CSS,以删除微调框,但我想完全摆脱这种行为。我喜欢使用type=number
它,因为它在iOS上带来了不错的键盘。
onscroll
处理程序时,会发生event.preventDefault()
什么?
是否可以禁用滚轮在输入数字字段中更改数字?我已经弄乱了特定于Webkit的CSS,以删除微调框,但我想完全摆脱这种行为。我喜欢使用type=number
它,因为它在iOS上带来了不错的键盘。
onscroll
处理程序时,会发生event.preventDefault()
什么?
Answers:
防止其他对象建议的输入数字元素上的mousewheel事件的默认行为(调用“ blur()”通常不是首选方法,因为这不是用户想要的)。
但。我会避免一直监听所有input-number元素上的mousewheel事件,而只在该元素处于焦点时(即存在问题的时候)才这样做。否则,当鼠标指针位于输入数字元素上的任意位置时,用户将无法滚动页面。
jQuery解决方案:
// disable mousewheel on a input number field when in focus
// (to prevent Cromium browsers change the value when scrolling)
$('form').on('focus', 'input[type=number]', function (e) {
$(this).on('wheel.disableScroll', function (e) {
e.preventDefault()
})
})
$('form').on('blur', 'input[type=number]', function (e) {
$(this).off('wheel.disableScroll')
})
(将焦点事件委托给周围的表单元素-避免使用许多对性能不利的事件侦听器。)
$(document).on("wheel", "input[type=number]", function (e) {
$(this).blur();
});
这类似于@Simon Perepelitsa在纯js中的回答,但有点简单,因为它将一个事件侦听器放在document元素上,并检查被关注元素是否为数字输入:
document.addEventListener("wheel", function(event){
if(document.activeElement.type === "number"){
document.activeElement.blur();
}
});
如果要关闭某些字段上的值滚动行为,但不关闭其他字段,请执行以下操作:
document.addEventListener("wheel", function(event){
if(document.activeElement.type === "number" &&
document.activeElement.classList.contains("noscroll"))
{
document.activeElement.blur();
}
});
有了这个:
<input type="number" class="noscroll"/>
如果输入具有noscroll类,则它不会在滚动时更改,否则所有内容都保持不变。
wheel
而不是mousewheel
。参考:developer.mozilla.org/zh-CN/docs/Web/API/Element/wheel_event PS。我不是投反对票的人。
input = document.getElementById("the_number_input")
input.addEventListener("mousewheel", function(event){ this.blur() })
对于jQuery示例和跨浏览器解决方案,请参见相关问题:
$(':input[type=number]' ).live('mousewheel',function(e){ $(this).blur(); });
我使用了模糊而不是阻止默认值,因此它不会阻止页面滚动!
live()
已弃用。现在,您应该使用on()
: $(':input[type=number]').on('mousewheel',function(e){ $(this).blur(); });
您可以简单地使用HTML onwheel属性。
此选项对滚动页面的其他元素没有影响。
并为所有输入添加侦听器,这些输入在以后动态创建的输入中不起作用。
另外,您可以使用CSS删除输入箭头。
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
input[type="number"] {
-moz-appearance: textfield;
}
<input type="number" onwheel="this.blur()" />
onBlur()
不是预期的。我设置了一个简单的方法return false
来真正地“不做任何事情”。 <input type="number" onwheel="return false;">
@Semyon Perepelitsa
有一个更好的解决方案。模糊将焦点从输入中移开,这是您不需要的副作用。您应该改用evt.preventDefault。这样可以防止用户滚动时输入的默认行为。这是代码:
input = document.getElementById("the_number_input")
input.addEventListener("mousewheel", function(evt){ evt.preventDefault(); })
首先,您必须通过以下任一方式停止mousewheel事件:
mousewheel.disableScroll
e.preventDefault();
el.blur();
前两种方法都停止了窗口的滚动,最后两种方法从元素上移开了焦点。两者都是不良的结果。
一种解决方法是el.blur()
延迟使用和重新调整元素的位置:
$('input[type=number]').on('mousewheel', function(){
var el = $(this);
el.blur();
setTimeout(function(){
el.focus();
}, 10);
});
var hadFocus = el.is(':focus');
在模糊之前进行一次测试,以查看元素是否具有焦点:然后进行保护,仅在hadFocs为true时设置超时。
对于任何使用React并寻求解决方案的人。我发现最简单的方法是在Input组件中使用onWheelCapture道具,如下所示:
onWheelCapture={e => {
e.target.blur()
}}
Typescript需要知道您正在使用HTMLElement来确保类型安全,否则您将看到很多Property 'type' does not exist on type 'Element'
类型的错误。
document.addEventListener("mousewheel", function(event){
let numberInput = (<HTMLInputElement>document.activeElement);
if (numberInput.type === "number") {
numberInput.blur();
}
});
在试图解决这个我自己,我注意到,它实际上可以保留页面输入的滚动和焦点,而试图通过重新火已捕获事件的父元素上禁用数量的变化<input type="number"/>
上,它被抓获,就像这样:
e.target.parentElement.dispatchEvent(e);
但是,这会导致浏览器控制台出错,并且可能无法保证在所有地方都能正常工作(我仅在Firefox上进行了测试),因为它是有意的无效代码。
至少在Firefox和Chromium上很好用的另一个解决方案是临时制作<input>
element readOnly
,如下所示:
function handleScroll(e) {
if (e.target.tagName.toLowerCase() === 'input'
&& (e.target.type === 'number')
&& (e.target === document.activeElement)
&& !e.target.readOnly
) {
e.target.readOnly = true;
setTimeout(function(el){ el.readOnly = false; }, 0, e.target);
}
}
document.addEventListener('wheel', function(e){ handleScroll(e); });
我注意到的一个副作用是,如果您对readOnly
字段具有不同的样式,则可能会导致字段短暂闪烁,但是至少就我而言,这似乎不是问题。
同样,(如James的回答所述)readOnly
您可以修改blur()
字段,然后再将focus()
其返回,而不是修改属性,但是同样,根据使用的样式,可能会出现一些闪烁。
另外,如此处其他评论所述,您可以preventDefault()
改为调用该事件。假设您只处理wheel
焦点在鼠标光标下方的数字输入上的事件(这是上面三个条件所表示的意思),那么对用户体验的负面影响将几乎没有。
如果您需要不需要JavaScript的解决方案,则可以将一些HTML功能与CSS伪元素结合使用,可以达到以下目的:
span {
position: relative;
display: inline-block; /* Fit around contents */
}
span::after {
content: "";
position: absolute;
top: 0; right: 0; bottom: 0; left: 0; /* Stretch over containing block */
cursor: text; /* restore I-beam cursor */
}
/* Restore context menu while editing */
input:focus {
position: relative;
z-index: 1;
}
<label>How many javascripts can u fit in u mouth?
<span><input type="number" min="0" max="99" value="1"></span>
</label>
之所以有效,是因为点击了 <label>
与表单字段相关联将使该字段集中。但是,该字段上的伪元素的“窗口窗格”将阻止鼠标滚轮事件到达它。
缺点是向上/向下微调器按钮不再起作用,但是您说您已经删除了那些按钮。
从理论上讲,可以还原上下文菜单而无需首先关注输入内容:用户滚动时不应触发:hover
样式,因为出于性能方面的考虑,浏览器会避免在滚动过程中重新计算样式,但我尚未彻底跨浏览器/设备测试了。
function fixNumericScrolling() {
$$( "input[type=number]" ).addEvent( "mousewheel", function(e) {
stopAll(e);
} );
}
function stopAll(e) {
if( typeof( e.preventDefault ) != "undefined" ) e.preventDefault();
if( typeof( e.stopImmediatePropagation ) != "undefined" ) e.stopImmediatePropagation();
if( typeof( event ) != "undefined" ) {
if( typeof( event.preventDefault ) != "undefined" ) event.preventDefault();
if( typeof( event.stopImmediatePropagation ) != "undefined" ) event.stopImmediatePropagation();
}
return false;
}