Detecting mousewheel on the x-axis (left and right) with Javascript

bob_cobb picture bob_cobb · May 30, 2012 · Viewed 15.3k times · Source

I know it's possible to detect up and down e.g.

    function handle(delta) {
    if (delta < 0) {
        alert('down');
} else {
    alert('up');
    }
}

function wheel(event){
    var delta = 0;
    if (!event) event = window.event;
    if (event.wheelDelta) {
        delta = event.wheelDelta/120; 
    } else if (event.detail) {
        delta = -event.detail/3;
    }
    if (delta)
        handle(delta);
        if (event.preventDefault)
                event.preventDefault();
        event.returnValue = false;
}

/* Initialization code. */
if (window.addEventListener)
    window.addEventListener('DOMMouseScroll', wheel, false);
window.onmousewheel = document.onmousewheel = wheel;​

But is there a way to detect if a user's mouse went left or right with the mousewheel?

Answer

robocat picture robocat · Oct 12, 2012

Internet Explorer: In IE9 and IE10 you have to use the onwheel event (not the onmousewheel, nor DOMMouseScroll) using addEventListener to be able to detect the horizontal wheel scrolling from the DOM. Use the event.deltaX value along with the event.deltaMode value to detect horizontal mouse wheeling (for vertical wheeling use the event.deltaY value). For <= IE8 use the onmousewheel event and the event.wheelDelta (only yaxis mouse wheeling supported for older IE versions).

Blink/Webkit: Support since Chrome 31/Safari 7 for the onwheel event. Otherwise use the onmousewheel event and the event.wheelDeltaX and event.wheelDeltaY properties. Chrome/Safari only trick: using the SHIFT key while mousewheeling scrolls left/right (useful for testing).

Firefox: Firefox 17 and higher support the onwheel event. To support older versions of Firefox (back to 3.6) use the now deprecated DOMMouseScroll and the event.axis and event.detail properties to support horizontal scrolling. (Firefox mobile: the docs imply that the onwheel event will fire when panning using a touch device. I haven't tried it.). Firefox also has a MozMousePixelScroll event. The MDN documentation also gives suggested code to handle the different events across browsers. Firefox also has a mousewheel.enable_pixel_scrolling configuration which may affect all the different wheel events.

Try the onwheel event out yourself using the wheel event tester from QuirksMode. I could see this working using IE9 on Win7, and IE10 on Windows 8 (release preview, IE version 10.0.8400.0). To setup for the new standard onwheel event:

  • Select addEventListener (capture) radio.
  • Untick scroll.
  • Untick mousewheel.
  • Leave wheel ticked.
  • Tick show event properties at bottom of right column.
  • Use F12 and confirm that the document is in documentMode IE9 Standards or IE10 Standards.
  • Do some mouse wheeling on the centre column and see the wheel events get logged in the left column, and the wheel event details show at the bottom of the right column.
  • Sometimes you might need to untick and retick the wheel event checkbox to get events (not sure why: maybe bug in quirksmode page or in IE?)

The W3C specification, the Microsoft IE9 documentation for the MouseWheel event and the MDN docs specify for the onwheel event:

  • deltaX - Gets the distance that a mouse wheel has rotated around the x-axis (horizontal).
  • deltaY - Gets the distance that a mouse wheel has rotated around the y-axis (vertical).
  • deltaZ - Gets the distance that a mouse wheel has rotated around the z-axis.
  • deltaMode - Gets a value that indicates the unit of measurement for delta values:
    • DOM_DELTA_PIXEL (0x00) Default. The delta is measured in pixels.
    • DOM_DELTA_LINE (0x01) The delta is measured in lines of text.
    • DOM_DELTA_PAGE (0x02) The delta is measured in pages of text.

Edit: make sure you DO NOT preventDefault() the event if event.ctrlKey is set, otherwise you will probably prevent page zooming. Also apparently the ctrlKey is set to true if you use pinch-zoom on a touchpad in Chrome and IE.

Feature detection is difficult in IE:

  • In IE10 with IE8 documentMode, 'onwheel' in document returns true but it seems that no events are fired for horizontal or vertical onwheel event.
  • In IE9 'onwheel' in document returns false but the onwheel event works (I guess that document.documentMode === 9 should be checked before using the onwheel event in IE9).
  • In IE9 and IE10 traditional document.onwheel = 'somefunc(event)' doesn't seem to work even in documentMode 9 or 10 (i.e. looks like you can only use addEventListener).

To test, use a Microsoft tiltwheel mouse, a scrolling touchpad (gesture or zone), or an Apple device (magic mouse or mighty mouse scrollball). Play with various mouse or touchpad settings in windows (or mouse preferences on OSX if testing horizontal scrolling on OSX with Safari).

The signs of the delta values have the opposite sign for onwheel and onmousewheel for all browsers. In IE the delta values are different for onwheel and onmousewheel, for example (using my dev machine with IE9 with a very standard Microsoft mouse):

  • event.deltaY was 111 on Win8 or 72 on Win7 for onwheel event scrolling down one notch. The value changes slightly with zoom, but there is some other factor involved as well that I can't work out (doesn't seem to be font-size).
  • event.wheelDelta was -120 for onmousewheel event scrolling down one notch.

  • For Windows XP "We have to add support for the WM_MOUSEHWHEEL message to make that work [, support] was added in Vista so if you are using XP you need IntelliType Pro and/or IntelliPoint installed" - as per this article.

  • Various common touchpad and mouse drivers bust the mouse wheel support for browsers e.g. broken browser detection, or using the WM_HSCROLL and WM_VSCROLL messages instead of the WM_MOUSEWHEEL and WM_MOUSEHWHEEL messages. So so drivers will not generate wheel events in the browser (regardless of which browser you used, or which version of Windows you used). A search of Bugzilla for WM_VSCROLL shows problems that could affect any browser (not just Firefox).