如何在不实际滚动的情况下确定滚动方向

60
我正在编写一个页面,在用户第一次滚动时,并不会实际滚动页面,而是添加一个带有过渡效果的类。 我想检测用户向下滚动的情况,因为如果他向上滚动,我希望它做其他事情。 我找到的所有方法都是基于定义当前body的scrollTop,然后在页面滚动后与body的scrollTop进行比较,以定义方向,但由于页面实际上并没有滚动,所以body的scrollTop()不会改变。
animationIsDone = false;

function preventScroll(e) {

    e.preventDefault();
    e.stopPropagation();
}

$('body').on('mousewheel', function(e) {

    if (animationIsDone === false) {
        $("#main-header").removeClass("yellow-overlay").addClass("yellow-overlay-darker");
        $(".site-info").first().addClass("is-description-visible");
        preventScroll(e);

        setTimeout(function() {
            animationIsDone = true;
        }, 1000);

    }


});

这就是我所想到的,但这种方式无论我向哪个方向滚动都会触发事件。


请注意,mousewheel已被弃用且不是标准的。虽然只有FireFox不支持它。为了支持FireFox,您可以尝试处理DOMMouseScroll,在DOMMouseScroll事件处理程序中,相当于mousewheel事件处理程序中的e.wheelDelta约为-40*e.detail。此外,看起来jQuery删除了该属性,您必须访问originalEvent - King King
你可以使用**wheel event。在这里,你可以查看一个具有跨浏览器支持的示例,处理滚动:stackoverflow.com/questions/4989632...**。 - jherax
6个回答

153
mousewheel 事件正在迅速过时,您应该改用 wheel 事件。

这样可以轻松地在没有滚动条的情况下确定垂直和/或水平滚动方向。

此事件在所有主流浏览器中都得到了支持,并且应该在未来保持标准。

以下是演示代码:

window.addEventListener('wheel', function(event)
{
 if (event.deltaY < 0)
 {
  console.log('scrolling up');
  document.getElementById('status').textContent= 'scrolling up';
 }
 else if (event.deltaY > 0)
 {
  console.log('scrolling down');
  document.getElementById('status').textContent= 'scrolling down';
 }
});
<div id="status"></div>


6
因为用实际的 JavaScript 回答了一个问题(而不是使用框架/库),所以我给你点了赞。 - John
我该如何使用 dispatchEvent 触发向上或向下滚动的事件? - Shayan
4
这个能不能在触摸设备上运行(检测滑动滚动尝试)? - Trever Thompson

23

尝试使用addEventListener来实现这个功能。

window.addEventListener('mousewheel', function(e){
    wDelta = e.wheelDelta < 0 ? 'down' : 'up';
    console.log(wDelta);
});

演示

更新:

正如其中一个答案中提到的,mousewheel事件已经过时了。应该使用wheel事件。


1
非常感谢,运行得很好。这是一个未缩短的版本,以防其他人需要它(对于初学者来说可能难以阅读)。 - Daniel Ortiz
3
如www139的回答所述,mousewheel事件已经被弃用。相反,您应该使用wheel事件(请参考www139的回答)。 - user993683

4

我知道这篇文章是5年前的,但我没有看到任何好的Jquery答案(.on('mousewheel')对我不起作用...)

使用jQuery的简单答案,并使用window而不是body以确保你正在处理滚动事件:

$(window).on('wheel', function(e) {
    var scroll = e.originalEvent.deltaY < 0 ? 'up' : 'down';
    console.log(scroll);
});

3
尝试使用e.wheelDelta
var animationIsDone = false, scrollDirection = 0;

function preventScroll(e) {

    e.preventDefault();
    e.stopPropagation();
}

$('body').on('mousewheel', function(e) {

    if (e.wheelDelta >= 0) {
        console.log('Scroll up'); //your scroll data here
    }
    else {
        console.log('Scroll down'); //your scroll data here
    }
    if (animationIsDone === false) {
        $("#main-header").removeClass("yellow-overlay").addClass("yellow-overlay-darker");
        $(".site-info").first().addClass("is-description-visible");
        preventScroll(e);

        setTimeout(function() {
            animationIsDone = true;
        }, 1000);

    }


});

注意:请记住,MouseWheel已被弃用,并且不支持在FireFox中使用。

非常感谢..我会注意鼠标滚轮的问题 =) - Daniel Ortiz

2

这个能在React应用中工作。

<p onWheel={this.onMouseWheel}></p> 

添加事件监听器后,您可以使用deltaY来捕获鼠标滚轮。

onMouseWheel = (e) => {
 e.deltaY > 0 
   ? console.log("Down")
   : console.log("up")
}

1

在 Chrome 上测试通过。

$('body').on('mousewheel', function(e) {

    if (e.originalEvent.deltaY >= 0) {
        console.log('Scroll up'); //your scroll data here
    }
    else {
        console.log('Scroll down'); //your scroll data here
    }

});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接