jQuery滚动事件:如何确定以像素为单位滚动的数量(滚动增量)?

And*_*yev 13 javascript jquery

我有这个事件:

$(window).scroll(function(e){    
    console.log(e);
})
Run Code Online (Sandbox Code Playgroud)

我想知道,我有多少像素滚动值,因为我认为,滚动值取决于窗口大小和屏幕分辨率.

函数参数e不包含此信息.
我可以$(window).scrollTop()在每次滚动后存储并计算差异,但我可以采用不同的方式吗?

not*_*ary 20

"滚动值"不依赖于窗口大小或屏幕分辨率."滚动值"只是滚动的像素数.

但是,您是否能够完全滚动,并且可以滚动的数量取决于容器的可用空间和容器内容的大小(在这种情况下是容器document.documentElement,或者document.body是旧浏览器).

您是正确的,该scroll事件不包含此信息.它不提供delta指示滚动的像素数的属性.对于本机scroll事件和jQuery scroll事件都是如此.这似乎是一个有用的功能,类似于mousewheel事件如何为X和Y delta提供属性.

我不知道,也不会推测,为什么权力没有提供delta财产scroll,但这超出了这个问题的范围(随意发表一个单独的问题).

您使用的存储scrollTop在变量中并将其与当前scrollTop值进行比较的方法是我找到的最好(也是唯一)方法.但是,根据本文,您可以通过扩展jQuery来提供新的自定义事件来简化此操作:http://learn.jquery.com/events/event-extensions/

这是我创建的一个示例扩展,用于窗口/文档滚动.这是一个自定义事件scrolldelta,它自动跟踪X和Y delta(分别为scrollLeftDeltascrollTopDelta).我没有尝试过其他元素; 将此作为练习给读者.这适用于Chrome和Firefox的当前版本.它使用的伎俩用于获取的总和document.documentElement.scrollTop,并document.body.scrollTop处理其中的Chrome更新的bug body.scrollTop,而不是documentElement.scrollTop(IE和FF更新documentElement.scrollTop;见https://code.google.com/p/chromium/issues/detail?id=2891).

JSFiddle演示:http://jsfiddle.net/tew9zxc1/

Runnable Snippet(向下滚动并单击Run code snippet):

// custom 'scrolldelta' event extends 'scroll' event
jQuery.event.special.scrolldelta = {
    delegateType: "scroll",
    bindType: "scroll",
    handle: function (event) {
        var handleObj = event.handleObj;
        var targetData = jQuery.data(event.target);
        var ret = null;
        var elem = event.target;
        var isDoc = elem === document;
        var oldTop = targetData.top || 0;
        var oldLeft = targetData.left || 0;
        targetData.top = isDoc ? elem.documentElement.scrollTop + elem.body.scrollTop : elem.scrollTop;
        targetData.left = isDoc ? elem.documentElement.scrollLeft + elem.body.scrollLeft : elem.scrollLeft;
        event.scrollTopDelta = targetData.top - oldTop;
        event.scrollTop = targetData.top;
        event.scrollLeftDelta = targetData.left - oldLeft;
        event.scrollLeft = targetData.left;
        event.type = handleObj.origType;
        ret = handleObj.handler.apply(this, arguments);
        event.type = handleObj.type;
        return ret;
    }
};

// bind to custom 'scrolldelta' event
$(window).on('scrolldelta', function (e) {
    var top = e.scrollTop;
    var topDelta = e.scrollTopDelta;
    var left = e.scrollLeft;
    var leftDelta = e.scrollLeftDelta;
  // do stuff with the above info; for now just display it to user
    var feedbackText = 'scrollTop: ' + top.toString() + 'px (' + (topDelta >= 0 ? '+' : '') + topDelta.toString() + 'px), scrollLeft: ' + left.toString() + 'px (' + (leftDelta >= 0 ? '+' : '') + leftDelta.toString() + 'px)';
    document.getElementById('feedback').innerHTML = feedbackText;
});
Run Code Online (Sandbox Code Playgroud)
#content {
    /* make window tall enough for vertical scroll */
    height: 2000px;
    /* make window wide enough for horizontal scroll */
    width: 2000px;
    /* visualization of scrollable content */
    background-color: blue;
}
#feedback {
    border:2px solid red;
    padding: 4px;
    color: black;
    position: fixed;
    top: 0;
    height: 20px;
    background-color: #fff;
    font-family:'Segoe UI', 'Arial';
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='feedback'>scrollTop: 0px, scrollLeft: 0px</div>
<div id='content'></div>
Run Code Online (Sandbox Code Playgroud)

请注意,您可能需要根据您的操作去除事件.你没有在你的问题中提供太多的上下文,但如果你给出一个更好的例子来说明你实际使用这些信息,我们可以提供更好的答案.(请显示更多代码,以及如何使用"滚动值").


som*_*ere 6

要确定滚动的像素数量,您必须记住,scroll事件几乎会在您移动的每个像素上被触发.完成它的方法是保存先前的滚动值并在超时中进行比较.像这样:

var scrollValue = 0;
var scrollTimeout = false

$(window).scroll(function(event){
    /* Clear it so the function only triggers when scroll events have stopped firing*/
    clearTimeout(scrollTimeout);
    /* Set it so it fires after a second, but gets cleared after a new triggered event*/
    scrollTimeout = setTimeout(function(){
        var scrolled = $(document).scrollTop() - scrollValue;
        scrollValue = $(document).scrollTop();
        alert("The value scrolled was " + scrolled);
    }, 1000);
});
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您可以在滚动后获得滚动一秒的数量(这是可调整的,但您必须记住,今天如此流行的平滑滚动有一些用完的时间,而您不希望在完全停止之前触发) .

  • 它可以降低使用的资源量,并且只在滚动结束时调用您的函数.这主要是因为现代浏览器在感觉自然的情况下继续滚动一点点.每秒对几百个事件调用jQuery函数有点过分了. (3认同)