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

时间:2012-03-15 00:17:28

标签: javascript html css html5 forms

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

18 个答案:

答案 0 :(得分:75)

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

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

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('mousewheel.disableScroll', function (e) {
    e.preventDefault()
  })
})
$('form').on('blur', 'input[type=number]', function (e) {
  $(this).off('mousewheel.disableScroll')
})

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

答案 1 :(得分:23)

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

答案 2 :(得分:18)

input = document.getElementById("the_number_input")
input.addEventListener("mousewheel", function(event){ this.blur() })

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

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

HTML5 event listener for number input scroll - Chrome only

答案 3 :(得分:13)

@Semyon Perepelitsa

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

input = document.getElementById("the_number_input")
input.addEventListener("mousewheel", function(evt){ evt.preventDefault(); })

答案 4 :(得分:13)

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

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

document.addEventListener("mousewheel", function(event){
    if(document.activeElement.type === "number"){
        document.activeElement.blur();
    }
});

如果您想关闭某些字段而不是其他字段的值滚动行为,请改为执行此操作:

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

用这个:

<input type="number" class="noscroll"/>

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

答案 5 :(得分:6)

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

  1. 使用mousewheel.disableScroll
  2. 停用它
  3. 使用e.preventDefault();
  4. 拦截它
  5. 通过从元素el.blur();
  6. 中移除焦点

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

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

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

答案 6 :(得分:5)

您可以简单地使用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()" />

答案 7 :(得分:3)

我有另一个建议。我对触发模糊事件的大多数常见建议所遇到的问题是,它具有意外的副作用。意外删除焦点状态并不总是一件好事。

为什么不是呢?

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

这非常简单明了,易于实现,并且没有我能想到的副作用。

答案 8 :(得分:3)

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

答案 9 :(得分:2)

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

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

答案 10 :(得分:2)

提供的答案在Firefox(Quantum)中不起作用。需要将事件监听器从鼠标滚轮更改为滚轮:

$(':input[type=number]').on('wheel',function(e){ $(this).blur(); });

此代码适用于Firefox Quantum和Chrome。

答案 11 :(得分:0)

在尝试自己解决此问题时,我注意到实际上可以保留页面的滚动和输入的焦点,同时通过尝试在{{ 1}}被捕获,就像这样:

<input type="number"/>

但是,这会导致浏览器控制台出现错误,并且可能无法保证在所有地方都能正常工作(我仅在Firefox上进行了测试),因为它是故意无效的代码。

另一种至少在Firefox和Chromium上有效的解决方案是临时制作e.target.parentElement.dispatchEvent(e); 元素<input>,如下所示:

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); }); 字段使用不同的样式,则可能会导致字段瞬间闪烁,但是至少就我而言,这似乎没有成为一个问题。

同样,(如James的回答所述)无需修改readOnly属性,您可以readOnly字段,然后blur()将该字段返回,但同样,取决于样式使用时,可能会出现一些闪烁。

或者,如此处其他注释中所述,您可以仅在事件上调用focus()。假设您只处理焦点在鼠标光标下的数字输入上的preventDefault()个事件(这就是上面三个条件所表示的意思),那么对用户体验的负面影响将几乎没有。

答案 12 :(得分:0)

打字稿变体

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

答案 13 :(得分:0)

如果您想要不需要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样式不应在用户滚动时触发,因为浏览器避免在滚动过程中重新计算它们出于性能方面的考虑,但我尚未对跨浏览器/设备进行全面的测试。

答案 14 :(得分:0)

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

答案 15 :(得分:0)

即使光标没有悬停在数字元素上,大多数答案也会模糊数字元素;下面没有

document.addEventListener("wheel", function(event) {
  if (document.activeElement.type === "number" &&
    document.elementFromPoint(event.x, event.y) == document.activeElement) {
    document.activeElement.blur();
  }
});

https://jsfiddle.net/s06puv3j/1/

答案 16 :(得分:0)

我一直在努力寻找解决方案。所以,这篇文章和其他帖子帮助我做到了这一点。我们需要在这里更改有关最佳答案的一些内容。所以为了禁用滚动,我们必须添加以下内容:

<script>
$(document).ready(function() {
    $('input[type=number]').on('wheel',function(e){ $(this).blur(); }); 
});
</script>

我们使用“wheel”而不是“onwheel” :)

答案 17 :(得分:0)

Antd / React + Typescript 答案

https://api.trello.com/1/boards/{board}/cards?filter=closed&key={key}&token={token}
# ---------------------------------------------------^^^^^^