最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Increment input value using mouse wheel - Stack Overflow

programmeradmin0浏览0评论

I'm trying to increase/decrease the value of input field using mouse wheel. I've put together the following code. It's working fine, but there's a small problem.

The behaviour I want is to be able to increment/decrement the input value using mouse wheel once I focus on the element. Mouse doesn't have to be hovering the element. The following code performs this. But if I use wheel while hovering the input element, the value is incremented/decremented by 2 instead of 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=".1.1/jquery.min.js"></script>
<input type="number" value="0" min="0" max="255" />

I'm trying to increase/decrease the value of input field using mouse wheel. I've put together the following code. It's working fine, but there's a small problem.

The behaviour I want is to be able to increment/decrement the input value using mouse wheel once I focus on the element. Mouse doesn't have to be hovering the element. The following code performs this. But if I use wheel while hovering the input element, the value is incremented/decremented by 2 instead of 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./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="number" value="0" min="0" max="255" />

After some experimenting, I figured that there's a similar behaviour for up and down arrow keys. Up and down arrow keys, on a number input, increments/decrements the value. And I suppose, this behaviour conflicts with my code. Causes it to increment by 2, even though the code doesn't execute twice.


I've just realized that this might be a Chrome specific problem. Chrome let's you increment/decrement number input value using mouse wheel if you focus and hover the element. However, it works in a really weird way.

If I just add <input type="number" /> in a blank HTML page, this mouse wheel increment doesn't work. To make it work, I simply add window.onwheel = function() {};. This doesn't make any sense. Also this seems to work on JSFiddle and JSBin without onwheel assignment on the window.


Going back to the actual problem, can I disable the default mouse wheel increment on the element, so that I can use my custom one? Or is there another approach that I can use?

Share Improve this question edited Aug 21, 2020 at 11:27 Brian Tompsett - 汤莱恩 5,89372 gold badges61 silver badges133 bronze badges asked Aug 22, 2016 at 21:30 akinuriakinuri 12.1k10 gold badges75 silver badges107 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 4

I'm not sure why you would be considering not using preventDefault() to prevent the default action. You are changing what the UI action will be under these circumstances. You should, of course, use preventDefault() to prevent the default action. If you don't use preventDefault() then there would be some unexpected consequences to using the scroll wheel when the <input type="number"> is focused. Without preventDefault(), what bination of unexpected consequences would occur under those conditions will depend on the browser that is being used to view the page.

I am unable to duplicate a conflict with using the cursor keys to change the input value. Obviously, if all you are using to limit the minimum and maximum values of the <input> is the code for the mouse wheel, then those limits will not function for any other method of entry. You could use the min and max attributes for limiting values. Doing so would be better for multiple reasons, including that it affects all methods of entering a value and as it allows defining those ranges per <input> instead of one set of limits for all <input type="number">. I have changed the code so that your code also uses these attributes.

If you do this, you may want to consider adding a CSS style to indicate that the <input type="number"> element has focus. Doing so will make it more clear to the user why the mouse wheel is not doing what they normally expect from their browser's UI.

I suggest you try this with multiple browsers to see if it is something you desire. Personally, at least in the testing I have done on this page, I like the behavior.

NOTE:
Your use of the focus and blur events is overly plex. I have changed the code to directly find the focused element using document.activeElement.

//Exclude one specific element for paring 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 parison 
    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 paring UIs: May conflict with browser default, or user's theme.*/
#exclude:focus {
  box-shadow: none;
}
<script src="https://ajax.googleapis./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"/>

发布评论

评论列表(0)

  1. 暂无评论