How to know the scroll direction of the mouse wheel

Asked

Viewed 1,351 times

13

How to know the direction and quantity of the scroll when scrolling with the mouse wheel?

Browsers have different ways of passing information on the object event. Some use the .wheelDelta, others the .detail, and others (new generation) use the DOM3 event wheel passing relevant information on deltaY or deltaX.

What better way to consistently know the direction and eventually the amount of scroll in different browsers?

To complete the question I leave a search I did on this, and making the mouse wheel rotate forward:

| mousewheel        | Chrome (win) | Chrome (mac) | Firefox (win) | Firefox (mac) | Safari 7 (mac) | Opera 22 (mac) | Opera 22 (win) | IE11      | IE 9 & 10   | IE 7 & 8  |
|-------------------|--------------|--------------|---------------|---------------|----------------|----------------|----------------|-----------|-------------|-----------|
| event.detail      | 0            | 0            | -             | -             | 0              | 0              | 0              | 0         | 0           | undefined |
| event.wheelDelta  | 120          | 120          | -             | -             | 12             | 120            | 120            | 120       | 120         | 120       |
| event.wheelDeltaY | 120          | 120          | -             | -             | 12             | 120            | 120            | undefined | undefined   | undefined |
| event.wheelDeltaX | 0            | 0            | -             | -             | 0              | 0              | 0              | undefined | undefined   | undefined |
| event.delta       | undefined    | undefined    | -             | -             | undefined      | undefined      | undefined      | undefined | undefined   | undefined |
| event.deltaY      | -100         | -4           | -             | -             | undefined      | -4             | -100           | undefined | undefined   | undefined |
| event.deltaX      | 0            | 0            | -             | -             | undefined      | 0              | 0              | undefined | undefined   | undefined |
|                   |              |              |               |               |                |                |                |           |             |           |
| wheel             | Chrome (win) | Chrome (mac) | Firefox (win) | Firefox (mac) | Safari 7 (mac) | Opera 22 (mac) | Opera 22 (win) | IE11      | IE 10 & 9   | IE 7 & 8  |
| event.detail      | 0            | 0            | 0             | 0             | -              | 0              | 0              | 0         | 0           | -         |
| event.wheelDelta  | 120          | 120          | undefined     | undefined     | -              | 120            | 120            | undefined | undefined   | -         |
| event.wheelDeltaY | 120          | 120          | undefined     | undefined     | -              | 120            | 120            | undefined | undefined   | -         |
| event.wheelDeltaX | 0            | 0            | undefined     | undefined     | -              | 0              | 0              | undefined | undefined   | -         |
| event.delta       | undefined    | undefined    | undefined     | undefined     | -              | undefined      | undefined      | undefined | undefined   | -         |
| event.deltaY      | -100         | -4           | -3            | -0,1          | -              | -4             | -100           | -99,56    | -68,4 | -53 | -         |
| event.deltaX      | 0            | 0            | 0             | 0             | -              | 0              | 0              | 0         | 0           | -         |
|                   |              |              |               |               |                |                |                |           |             |           |
|                   |              |              |               |               |                |                |                |           |             |           |
| DOMMouseScroll    |              |              | Firefox (win) | Firefox (mac) |                |                |                |           |             |           |
| event.detail      |              |              | -3            | -1            |                |                |                |           |             |           |
| event.wheelDelta  |              |              | undefined     | undefined     |                |                |                |           |             |           |
| event.wheelDeltaY |              |              | undefined     | undefined     |                |                |                |           |             |           |
| event.wheelDeltaX |              |              | undefined     | undefined     |                |                |                |           |             |           |
| event.delta       |              |              | undefined     | undefined     |                |                |                |           |             |           |
| event.deltaY      |              |              | undefined     | undefined     |                |                |                |           |             |           |
| event.deltaX      |              |              | undefined     | undefined     |                |                |                |           |             |           |
  • 1

    The reason for this question and answer is because I’ve been fixing a bug about it in a Javascript library. I publish here the answer I came to. If there are flaws or better ways to do it would be interesting to see here. There is a related question at Soen, but who did not give me the full answer...

1 answer

9


I found 2 approaches from the same idea.

First approach, make a function that returns the original and relevant value to the mouse wheel in different browsers, adjusting negative values for the direction to be consistent.

var roda = (event.wheelDelta) ? event.wheelDelta : -(event.detail || event.deltaY);

Example: http://jsfiddle.net/RzPPp/

In this variant it is still possible to reduce the movement to only +1 or -1 to be used as a direction indicator: http://jsfiddle.net/RzPPp/1/

The other approach, more complex is to try to normalize the value to have the same behavior in different browsers. I used the question table to realize that browsers use multiples of a base number to show the speed/amount the wheel moves. Using this information, I checked the results to find out via "Feature Detect" (or more exactly "multiple Tect") which browser and how this value should be treated.

So I came to this code:

var normalized;
if (event.wheelDelta) {
    normalized = (event.wheelDelta % 120 - 0) == -0 ? event.wheelDelta / 120 : event.wheelDelta / 12;
} else {
    var rawAmmount = event.deltaY ? event.deltaY : event.detail;
    normalized = -(rawAmmount % 3 ? rawAmmount * 10 : rawAmmount / 3);
}

Example: http://jsfiddle.net/RzPPp/2/

function normalizarRoda(event) {
    var normalized;
    if (event.wheelDelta) {
        normalized = (event.wheelDelta % 120 - 0) == -0 ? event.wheelDelta / 120 : event.wheelDelta / 12;
    } else {
        var rawAmmount = event.deltaY ? event.deltaY : event.detail;
        normalized = -(rawAmmount % 3 ? rawAmmount * 10 : rawAmmount / 3);
    }
    return normalized;
}

Note: Because different browsers use different events, you need to "listen" to the right event. So to tie an event headset use so, to detect which the right browser and the event it should "listen to":

var event = 'onwheel' in document ? 'wheel' : 'onmousewheel' in document ? 'mousewheel' : 'DOMMouseScroll';
meuElemento.addEventListener(event, callback);

I tested this answer on IE7~11, Firefox (latest) Win and Mac, Safari 7, Chrome (latest) Win and Mac, Opera (latest) Win and Mac. I also noticed that the Mac platform is more generous in returning values. Thus on Mac the values of a very fast run are higher than those of Windows, but equal between browsers of the same platform. The minimum value is the same.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.