0

So I'm using mousewheel.js to handle mousewheel scrolling in any part of the document so I can scroll a custom scroller made by Nicescroll.

You can check a fiddle of it working here

Here's part of the code that handles the scrolling:

function activate_mousewheel()
{
    $(document).bind('mousewheel', function(event, delta, deltaX, deltaY) 
    {
        if(delta < 0)
        {
            console.log(1);
            $('#postscroller').scrollTop($('#postscroller').scrollTop() + 60);
        }
        else
        {
            console.log(2);
            $('#postscroller').scrollTop($('#postscroller').scrollTop() - 60);
        }
    });
}

Now my problem is that when this is used in a computer with a touchpad with horizontal scrolling enabled the movement is all jittery rendering it unusable. So this problem will affect people using any kind of laptop with horizontal scrolling like a chromebook or a macbook.

I've tried doing various fixes, playing with the deltas but to no avail.

I was hoping someone here could find a solution.

Thanks.

madprops
  • 3,909
  • 5
  • 34
  • 42

2 Answers2

1

The mousewheel event fires a lot of times. So to regulate the event, so it doesn't fire as much, use a throttle function.

https://lodash.com/docs#throttle

Because the event will not fire as often, the performance should be better.

function onMouseWheel(event, delta, deltaX, deltaY) 
{
    if(delta < 0)
    {
        console.log(1);
        $('#postscroller').scrollTop($('#postscroller').scrollTop() + 60);
    }
    else
    {
        console.log(2);
        $('#postscroller').scrollTop($('#postscroller').scrollTop() - 60);
    }
});

function activate_mousewheel()
{
    $(document).bind('mousewheel', _.throttle(onMouseWheel, 100);
}
blablabla
  • 1,468
  • 15
  • 17
1

I had to find a solution for the problem myself, and after hours of trying and beeing creative here is what i came up with. Of course you have to modify it to integrate it to work smoothly with nicescroll etc. as this is plain JS:

Well I needed to get a solution. So I found a acceptable solution for this problem:

var scrolling = false;
var oldTime = 0;
var newTime = 0;
var isTouchPad;
var eventCount = 0;
var eventCountStart;

var mouseHandle = function (evt) {
    var isTouchPadDefined = isTouchPad || typeof isTouchPad !== "undefined";
    console.log(isTouchPadDefined);
    if (!isTouchPadDefined) {
        if (eventCount === 0) {
            eventCountStart = new Date().getTime();
        }

        eventCount++;

        if (new Date().getTime() - eventCountStart > 50) {
                if (eventCount > 5) {
                    isTouchPad = true;
                } else {
                    isTouchPad = false;
                }
            isTouchPadDefined = true;
        }
    }

    if (isTouchPadDefined) {
        // here you can do what you want
        // i just wanted the direction, for swiping, so i have to prevent
        // the multiple event calls to trigger multiple unwanted actions (trackpad)
        if (!evt) evt = event;
        var direction = (evt.detail<0 || evt.wheelDelta>0) ? 1 : -1;

        if (isTouchPad) {
            newTime = new Date().getTime();

            if (!scrolling && newTime-oldTime > 550 ) {
                scrolling = true;
                if (direction < 0) {
                    // swipe down
                } else {
                    // swipe up
                }
                setTimeout(function() {oldTime = new Date().getTime();scrolling = false}, 500);
            }
        } else {
            if (direction < 0) {
                // swipe down
            } else {
                // swipe up
            }
        }
    }
}

And registering the events:

document.addEventListener("mousewheel", mouseHandle, false);
document.addEventListener("DOMMouseScroll", mouseHandle, false);

Here is how it works:

When the user first scrolls, it will detect and check that in 50ms not more than 5 events got triggered, which is pretty unusual for a normal mouse, but not for a trackpad.

Then there is the else part, which is not for importance for the detection, but rather a trick to call a function once like when a user swipes. Please come at me if I wasn't clear enough, it was very tricky to get this working, and is of course a less than ideal workaround.

Edit: I optimized the code now as much as I can. It detects the mouseroll on the second time and swipe on trackpad instantly. Removed also a lot of repeating and unnecessary code.

David Fariña
  • 1,536
  • 1
  • 18
  • 28
  • 1
    Thank you so much, this worked pretty good, I just had to change the 550 and 500 values to 20 because otherwise the scrolling was way too slow, like 1 step per second. This definitely works, great job man. I need to wait 18 hours to give you the bounty though. – madprops Oct 22 '15 at 20:10
  • Glad it worked out! I remember having the same problem for my personal site and i was working on this particular detection for more than 10 hours just to get it working. I need to publish this somehow as i regularly see people answering "there is no solution to this". Well, my approach is theres always a solution :) No worries, im here for the help :) – David Fariña Oct 23 '15 at 12:15