使用鼠标滚轮增加输入值

Increment input value using mouse wheel

我正在尝试 increase/decrease 使用鼠标滚轮输入字段的值。我整理了以下代码。没问题,就是有个小问题。

我想要的行为是能够 increment/decrement 在我关注元素时使用鼠标滚轮输入值。鼠标不必悬停在元素上。以下代码执行此操作。但是,如果我在悬停输入元素时使用滚轮,则该值为 incremented/decremented x 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" />

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


我刚刚意识到这可能是一个 Chrome 特定问题。 Chrome 如果您将焦点悬停在元素上,让您 increment/decrement 使用鼠标滚轮输入数值。然而,它以一种非常奇怪的方式工作。

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


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

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

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

如果这样做,您可能需要考虑添加 CSS 样式以指示 <input type="number"> 元素具有焦点。这样做会让用户更清楚为什么鼠标滚轮没有按照他们通常对浏览器 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 Whosebug 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"/>