Binding to the scroll wheel when over a div
Asked Answered
K

5

30

I'm creating an image editor in the browser and I've got the code for all of my controls done. Now I'd like to map hot keys and mouse buttons. The keyboard is easy, but the mouse is not.

I need to detect when the mouse is over the canvas div and when the mouse wheel is moved above it. The mouse over part is not hard, its binding to the mouse wheel that I'm having trouble with.

I tried jQuery.scroll but that only seams to work if the div under the wheel is set to scroll itself. My canvas is not. It's offset is controlled via my scripts.

Things to note:

  • I'm using jQuery as my base.
  • I'm not acually scrolling anything, I'm trying to bind and event to the scroll wheel without actually scrolling.

Structure

<div id="pageWrap">
    [page head stuff...]
    <div id="canvas">
        [the guts of the canvas go here; lots of various stuff...]
    <div>
    [page body and footer stuff...]
</div>
Karp answered 15/9, 2010 at 7:25 Comment(0)
A
18

Important Update 01/2015 - mousewheel event deprecated:

In the meantime the mousewheel event is deprecated and replaced by wheel.

MDN Docs for mousewheel say:

Do not use this wheel event.

This interface is non-standard and deprecated. It was used in non-Gecko browsers only. Instead use the standard wheel event.


Now you should use something like:

// This function checks if the specified event is supported by the browser.
// Source: http://perfectionkills.com/detecting-event-support-without-browser-sniffing/
function isEventSupported(eventName) {
    var el = document.createElement('div');
    eventName = 'on' + eventName;
    var isSupported = (eventName in el);
    if (!isSupported) {
        el.setAttribute(eventName, 'return;');
        isSupported = typeof el[eventName] == 'function';
    }
    el = null;
    return isSupported;
}

$(document).ready(function() {
    // Check which wheel event is supported. Don't use both as it would fire each event 
    // in browsers where both events are supported.
    var wheelEvent = isEventSupported('mousewheel') ? 'mousewheel' : 'wheel';

    // Now bind the event to the desired element
    $('#foo').on(wheelEvent, function(e) {
        var oEvent = e.originalEvent,
            delta  = oEvent.deltaY || oEvent.wheelDelta;

        // deltaY for wheel event
        // wheelData for mousewheel event

        if (delta > 0) {
            // Scrolled up
        } else {
            // Scrolled down
        }
    });
});

P.S.

For the comment from Connell Watkins - "Could you explain the division by 120?",
there are some details on MSDN:

The onmousewheel event is the only event that exposes the wheelDelta property. This property indicates the distance that the wheel button has rotated, expressed in multiples of 120. A positive value indicates that the wheel button has rotated away from the user. A negative value indicates that the wheel button has rotated toward the user.

I left out the delta / 120 part in my method as there's no benefit IMO. Scrolling up is delta > 0 and down delta < 0. Simple.

Alica answered 27/1, 2015 at 13:50 Comment(1)
On Chrome v52 on Windows, at least, for scroll UP deltaY is -100 which breaks the above code. The following mod works with Chrome, IE and Firefox: var delta = onEvent.deltaY ? onEvent.deltaY * -1 : onEvent.wheelDelta;Lewls
C
29

A very easy implementation would look like:

$(document).ready(function(){
    $('#foo').bind('mousewheel', function(e){
        if(e.originalEvent.wheelDelta/120 > 0) {
            $(this).text('scrolling up !');
        }
        else{
            $(this).text('scrolling down !');
        }
    });
});​

http://www.jsfiddle.net/5t2MN/5/

Charactery answered 15/9, 2010 at 7:35 Comment(4)
Could you explain the division by 120?Coakley
I think it should be: e.originalEvent.wheelDelta. I've tested it on Chrome.Prakrit
Anyone looking to use jQuery 1.7+ should use e.originalEvent.wheelDelta as Esteban has suggested. You can view the fiddle here: http://jsfiddle.net/KyleMit/25btn/ The reason is that the event object in a jQuery event handler doesn't reflect the actual raised event. wheelData is a non-standard event property which is no longer passed into the jQuery event but is still available from the original source event which triggered the call.Attendant
Use DOMMouseScroll for Firefox.Inharmonic
A
18

Important Update 01/2015 - mousewheel event deprecated:

In the meantime the mousewheel event is deprecated and replaced by wheel.

MDN Docs for mousewheel say:

Do not use this wheel event.

This interface is non-standard and deprecated. It was used in non-Gecko browsers only. Instead use the standard wheel event.


Now you should use something like:

// This function checks if the specified event is supported by the browser.
// Source: http://perfectionkills.com/detecting-event-support-without-browser-sniffing/
function isEventSupported(eventName) {
    var el = document.createElement('div');
    eventName = 'on' + eventName;
    var isSupported = (eventName in el);
    if (!isSupported) {
        el.setAttribute(eventName, 'return;');
        isSupported = typeof el[eventName] == 'function';
    }
    el = null;
    return isSupported;
}

$(document).ready(function() {
    // Check which wheel event is supported. Don't use both as it would fire each event 
    // in browsers where both events are supported.
    var wheelEvent = isEventSupported('mousewheel') ? 'mousewheel' : 'wheel';

    // Now bind the event to the desired element
    $('#foo').on(wheelEvent, function(e) {
        var oEvent = e.originalEvent,
            delta  = oEvent.deltaY || oEvent.wheelDelta;

        // deltaY for wheel event
        // wheelData for mousewheel event

        if (delta > 0) {
            // Scrolled up
        } else {
            // Scrolled down
        }
    });
});

P.S.

For the comment from Connell Watkins - "Could you explain the division by 120?",
there are some details on MSDN:

The onmousewheel event is the only event that exposes the wheelDelta property. This property indicates the distance that the wheel button has rotated, expressed in multiples of 120. A positive value indicates that the wheel button has rotated away from the user. A negative value indicates that the wheel button has rotated toward the user.

I left out the delta / 120 part in my method as there's no benefit IMO. Scrolling up is delta > 0 and down delta < 0. Simple.

Alica answered 27/1, 2015 at 13:50 Comment(1)
On Chrome v52 on Windows, at least, for scroll UP deltaY is -100 which breaks the above code. The following mod works with Chrome, IE and Firefox: var delta = onEvent.deltaY ? onEvent.deltaY * -1 : onEvent.wheelDelta;Lewls
C
3

Have you tried mousewheel plugin?

http://www.ogonek.net/mousewheel/jquery-demo.html

Cheeseburger answered 15/9, 2010 at 7:30 Comment(1)
Ah, looks good. I'm wondering if this is possible without a plugin though.Karp
S
2

A simple example for bind mouse wheel with jquery....

<!DOCTYPE html>
<html>
<head>
<title>Mouse Wheel</title>
<script type='text/javascript' src='http://code.jquery.com/jquery-1.4.2.js'></script>
<style type='text/css'>
body { text-align: center; }
#res
{
    margin-top: 200px;
    font-size: 128px;
    font-weight: bold;
}
</style>
<script type='text/javascript'>
$(document).ready(function(){
    var num = 0;
    $(document).bind('mousewheel',function(e){
        if (e.wheelDelta == "120")
        {
            $("#res").text(++num);
        }
        else
        {
            $("#res").text(--num);
        }
    });
});
</script>
</head>
<body>
<div id="res">0</div>
</body>
</html>
Shears answered 28/11, 2012 at 8:58 Comment(0)
D
1

The e.wheelDelta didn't work for me.

This worked:

$(document).ready(function(){
    $('#foo').bind('mousewheel',function(e){
        if (e.originalEvent.wheelDelta == 120){
		//mouse up
        }
        else
        {
		//mouse down
        }
    });
});
Disparity answered 25/2, 2017 at 15:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.