禁用在`<input type = number>`上滚动

kjs*_*js3 103 html javascript css forms html5

是否可以禁用滚轮更改输入数字字段中的数字?我已经搞乱了特定于webkit的CSS来删除微调器,但我想完全摆脱这种行为.我喜欢使用,type=number因为它在iOS上带来了一个漂亮的键盘.

小智 79

防止鼠标事件在输入数字元素上的默认行为,如其他人建议的那样(调用"blur()"通常不是首选的方法,因为那不是,用户想要的).

但.我会避免一直在所有输入数字元素上监听鼠标滚轮事件,只有当元素处于焦点时才会这样做(当问题存在时).否则,当鼠标指针位于输入数字元素上方时,用户无法滚动页面.

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')
})
Run Code Online (Sandbox Code Playgroud)

(将焦点事件委托给周围的表单元素 - 以避免许多事件监听器,这对性能有害.)

  • 这似乎对Firefox不起作用. (4认同)
  • 对于不应该首先存在的行为,这是一个很好的修复. (3认同)
  • 很好的答案。我想如果我今天这样做,我会使用 Modernizr.touch 有条件地在非触摸设备上应用事件侦听器。基本上是下面 user2863715 所说的。 (2认同)

sto*_*roz 29

$(document).on("wheel", "input[type=number]", function (e) {
    $(this).blur();
});
Run Code Online (Sandbox Code Playgroud)

  • 这是完美的。 (2认同)

lwd*_*he1 23

ReactJS解决方案

对于那些需要 React 解决方案的人,这里有一个onWheel输入处理程序type="number",用于防止数字更改并防止用户尝试在输入上滚动时页面滚动。最后,它将重新关注输入,以便用户可以继续按预期进行编辑:

const numberInputOnWheelPreventChange = (e) => {
  // Prevent the input value change
  e.target.blur()

  // Prevent the page/container scrolling
  e.stopPropagation()

  // Refocus immediately, on the next tick (after the current function is done)
  setTimeout(() => {
    e.target.focus()
  }, 0)
}

return <input type="number" onWheel={numberInputOnWheelPreventChange}/>
Run Code Online (Sandbox Code Playgroud)


Sim*_*tsa 18

input = document.getElementById("the_number_input")
input.addEventListener("mousewheel", function(event){ this.blur() })
Run Code Online (Sandbox Code Playgroud)

http://jsfiddle.net/bQbDm/2/

对于jQuery示例和跨浏览器解决方案,请参阅相关问题:

数字输入滚动的HTML5事件监听器 - 仅限Chrome

  • 仅供参考,`live()`已被弃用.现在,你应该使用`on()`:`$(':input [type = number]').on('mousewheel',function(e){$(this).blur();});` (12认同)
  • @SaeidZebardast你的评论值得回答 (3认同)
  • 谢谢Seymon,我设法用这种方式用jQuery输入所有数字:`$(':input [type = number]').live('mousewheel',function(e){$(this).blur() ;});`我使用模糊而不是防止默认,所以它不会阻止页面滚动! (2认同)

Dib*_*ran 14

@Semyon Perepelitsa

有一个更好的解决方案.模糊会从输入中移除焦点,这是您不想要的副作用.你应该使用evt.preventDefault.这可以防止用户滚动时输入的默认行为.这是代码:

input = document.getElementById("the_number_input")
input.addEventListener("mousewheel", function(evt){ evt.preventDefault(); })
Run Code Online (Sandbox Code Playgroud)

  • 它有效,但事件不会冒泡,因此页面不会滚动.有没有办法保持默认行为(页面滚动)没有模糊? (6认同)

Pet*_*nyi 14

一个事件监听器来统治它们

这类似于@Semyon Perepelitsa在纯js中的答案,但有点简单,因为它在文档元素上放置一个事件监听器并检查焦点元素是否为数字输入:

document.addEventListener("mousewheel", function(event){
    if(document.activeElement.type === "number"){
        document.activeElement.blur();
    }
});
Run Code Online (Sandbox Code Playgroud)

如果要在某些字段上关闭值滚动行为,而不是其他字段,请执行以下操作:

document.addEventListener("mousewheel", function(event){
    if(document.activeElement.type === "number" &&
       document.activeElement.classList.contains("noscroll"))
    {
        document.activeElement.blur();
    }
});
Run Code Online (Sandbox Code Playgroud)

有了这个:

<input type="number" class="noscroll"/>
Run Code Online (Sandbox Code Playgroud)

如果输入具有noscroll类,则滚动时不会更改,否则一切都保持不变.

  • 谢谢,只有没有jquery的解决方案! (2认同)
  • 我看到这已被否决。如果您发现问题,请留下评论并投反对票。如果我错过了什么,我想了解它是什么。谢谢。 (2认同)
  • 对于现代浏览器,请使用事件 `wheel` 而不是 `mousewheel`。参考:https://developer.mozilla.org/en-US/docs/Web/API/Element/wheel_event 我不是那个投反对票的人。 (2认同)

Mai*_*eus 9

您只需使用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;
}
Run Code Online (Sandbox Code Playgroud)
<input type="number" onwheel="this.blur()" />
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢这个解决方案!谢谢。就我而言,`onBlur()`与预期的不一样。我设置了一个简单的“ return false”,而不是真正“无所事事”。`&lt;input type =“ number” onwheel =“ return false;”&gt;` (3认同)

Ale*_*mec 8

对于任何使用 React 并寻找解决方案的人。我发现最简单的方法是在 Input 组件中使用 onWheelCapture 道具,如下所示:

onWheelCapture={e => { e.target.blur() }}


小智 8

我有一个替代建议。我看到的大多数触发模糊事件的常见建议的问题是它具有意想不到的副作用。意外移除焦点状态并不总是一件好事。

为什么不是这个呢?

<input type="number" onwheel="return false;" />

它非常简单直接,易于实现,而且没有我能想到的副作用。

  • 对于 React / Next.js,我使用了这个 `onWheel={e =&gt; e.target.blur()}` 我不确定为什么 Mac 不提供禁用它的选项。 (7认同)
  • `onmousewheel="return false;"` 对我来说按预期工作。 (3认同)

vin*_*nyl 7

打字稿变体

Typescript 需要知道您正在使用 HTMLElement 以确保类型安全,否则您会看到很多Property 'type' does not exist on type 'Element'类型的错误。

document.addEventListener("wheel", function(event){
  const numberInput = (<HTMLInputElement>document.activeElement);
  if (numberInput.type === "number") {
    numberInput.blur();
  }
});
Run Code Online (Sandbox Code Playgroud)


TSl*_*tis 7

最简单的解决方案是添加onWheel={ event => event.currentTarget.blur() }}输入本身。


Jam*_* EJ 6

首先,您必须通过以下任一方式停止鼠标滚轮事件

  1. 用它禁用它 mousewheel.disableScroll
  2. 拦截它 e.preventDefault();
  3. 通过从元素中删除焦点 el.blur();

前两种方法都阻止窗口滚动,最后一种方法从元素中移除焦点; 两者都是不良后果.

一种解决方法是el.blur()在延迟后使用并重新聚焦元素:

$('input[type=number]').on('mousewheel', function(){
  var el = $(this);
  el.blur();
  setTimeout(function(){
    el.focus();
  }, 10);
});
Run Code Online (Sandbox Code Playgroud)

  • 一个好看的解决方案,但在测试中我发现这个解决方案具有窃取焦点的副作用.我调整了这个:测试元素是否具有焦点:`var hadFocus = el.is(':focus');`模糊之前,然后保护只在hadFocs为真时设置超时. (2认同)