【问题标题】:Increment input value using mouse wheel使用鼠标滚轮增加输入值
【发布时间】:2016-08-22 21:30:55
【问题描述】:

我正在尝试使用鼠标滚轮增加/减少输入字段的值。我整理了以下代码。它工作正常,但有一个小问题。

我想要的行为是,一旦我专注于元素,就能够使用鼠标滚轮增加/减少输入值。鼠标不必悬停在元素上。以下代码执行此操作。但是,如果我在悬停输入元素时使用滚轮,则该值会增加/减少 2 而不是 1。

var hoveredInput = null;

$('input[type="number"]').on("focus", function(e) {
  hoveredInput = this;
});
$('input[type="number"]').on("blur", function(e) {
  hoveredInput = null;
});

$(window).on("wheel", function(e) {
  if (hoveredInput) {
    if (e.originalEvent.deltaY < 0) {
      var currentValue = parseInt(hoveredInput.value, 10);
      var newValue = currentValue + 1;
      if (newValue > parseInt(hoveredInput.max, 10)) {
        newValue = hoveredInput.max;
      }
      hoveredInput.value = newValue;
    } else {
      var currentValue = parseInt(hoveredInput.value, 10);
      var newValue = currentValue - 1;
      if (newValue < parseInt(hoveredInput.min, 10)) {
        newValue = hoveredInput.min;
      }
      hoveredInput.value = newValue;
    }
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="number" value="0" min="0" max="255" />

经过一些试验,我发现向上和向下箭头键有类似的行为。向上和向下箭头键,在数字输入上,增加/减少值。而且我想,这种行为与我的代码冲突。导致它增加 2,即使代码没有执行两次。


我刚刚意识到这可能是 Chrome 特有的问题。如果您聚焦并悬停元素,Chrome 让您使用鼠标滚轮增加/减少数字输入值。但是,它的工作方式非常奇怪。

如果我只是在空白 HTML 页面中添加 &lt;input type="number" /&gt;,则此鼠标滚轮增量不起作用。为了使它工作,我只需添加window.onwheel = function() {};。这没有任何意义。这似乎也适用于JSFiddle 和JSBin,而没有window 上的onwheel 分配。


回到实际问题,我可以禁用元素上的默认鼠标滚轮增量,以便我可以使用自定义的吗?或者我可以使用其他方法吗?

【问题讨论】:

    标签: javascript google-chrome input dom-events mousewheel


    【解决方案1】:

    我不确定您为什么会考虑使用preventDefault() 来阻止默认操作。您正在更改在这些情况下的 UI 操作。当然,您应该使用preventDefault() 来阻止默认操作。如果你不使用preventDefault(),那么当&lt;input type="number"&gt; 被聚焦时使用滚轮会有一些意想不到的后果。如果没有preventDefault(),在这些情况下会发生什么意外后果组合将取决于用于查看页面的浏览器。

    我无法复制使用光标键更改输入值的冲突。显然,如果您用来限制&lt;input&gt; 的最小值和最大值的只是鼠标滚轮的代码,那么这些限制将不适用于任何其他输入方法。您可以使用minmax 属性来限制值。由于多种原因,这样做会更好,包括它会影响输入值的所有方法,并且因为它允许为每个 &lt;input&gt; 定义这些范围,而不是为所有 &lt;input type="number"&gt; 定义一组限制。我已更改代码,以便您的代码也使用这些属性。

    如果您这样做,您可能需要考虑添加 CSS 样式以指示 &lt;input type="number"&gt; 元素具有焦点。这样做可以让用户更清楚为什么鼠标滚轮没有按照他们通常期望的浏览器 UI 进行操作。

    我建议你在多个浏览器上试试这个,看看它是否是你想要的。就个人而言,至少在我在此页面上所做的测试中,我喜欢这种行为。

    注意:
    您对focusblur 事件的使用过于复杂。我已更改代码以使用document.activeElement 直接查找焦点元素。

    //Exclude one specific element for comparing this UI vs. the browser's default.
    var excludedEl = document.getElementById('exclude');
    
    $(window).on("wheel", function(e) {
      focusedEl = document.activeElement;
      if(focusedEl === excludedEl){
        //Exclude one specific element for UI comparison 
        return;
      }
      if (focusedEl.nodeName='input' && focusedEl.type && focusedEl.type.match(/number/i)){
        e.preventDefault();
        var max=null;
        var min=null;
        if(focusedEl.hasAttribute('max')){
          max = focusedEl.getAttribute('max');
        }
        if(focusedEl.hasAttribute('min')){
          min = focusedEl.getAttribute('min');
        }
        var value = parseInt(focusedEl.value, 10);
        if (e.originalEvent.deltaY < 0) {
          value++;
          if (max !== null && value > max) {
            value = max;
          }
        } else {
          value--;
          if (min !== null && value < min) {
            value = min;
          }
        }
        focusedEl.value = value;
      }
    });
    input[type="number"]:focus {
      box-shadow: 0px 0px 1.5px 1px cyan;
    }
    
    /*For comparing UIs: May conflict with browser default, or user's theme.*/
    #exclude:focus {
      box-shadow: none;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    NOTE: Events are only caught while the mouse stays within the test portion of the stackoverflow page:<br/><br/><br/>
    
    Uses changed UI (if focused, mouse wheel will increment/decrement):<br/>
    <input type="number" value="0" id="firstNumberInput" min="0" max="255"/>
    <br/>Uses browser default UI:
    <input id="exclude" type="number" value="0" min="0" max="255" style="display:block"/>

    【讨论】:

    • 这真是太愚蠢了,我没想到preventDefault()。我不知道document.activeElement。我还有另一个输入监听器来处理最小 - 最大限制。我只是不想包含它,因为它与手头的问题没有真正的关系。
    猜你喜欢
    • 1970-01-01
    • 2010-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-29
    • 1970-01-01
    相关资源
    最近更新 更多