我有这个事件:
$(window).scroll(function(e){
console.log(e);
})
我想知道,我有多少像素滚动值,因为我认为,滚动值取决于窗口大小和屏幕分辨率。
函数参数e
不包含此信息
我可以在每次滚动后存储$(window).scrollTop()
并计算差异,但我可以采用不同的方式吗?
答案 0 :(得分: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(分别为scrollLeftDelta
和scrollTopDelta
)。我没有尝试过其他元素;将此作为练习给读者。这适用于Chrome和Firefox的当前版本。它使用了获取document.documentElement.scrollTop
和document.body.scrollTop
之和的技巧来处理Chrome更新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;
});

#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';
}

<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>
&#13;
请注意,您可能需要根据您的操作去除事件。你没有在你的问题中提供很多上下文,但是如果你给出了一个更好的例子来说明你实际使用这些信息,我们可以提供更好的答案。 (请显示更多代码,以及如何使用&#34;滚动值&#34;)。
答案 1 :(得分: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);
});
通过这种方式,您可以在滚动后获得滚动一秒的数量(这是可调整的,但您必须记住,今天流行的平滑滚动有一些用完的时间,而且您不想在触发之前触发完全停止)。
答案 2 :(得分:1)
另一种方法呢?是的,可能,jQuery Mobile
我不欣赏这个解决方案,因为有必要包含大量的jQuery mobile。解决方案:
var diff, top = 0;
$(document).on("scrollstart",function () {
// event fired when scrolling is started
top = $(window).scrollTop();
});
$(document).on("scrollstop",function () {
// event fired when scrolling is stopped
diff = Math.abs($(window).scrollTop() - top);
});
答案 3 :(得分:1)
通过向Jquery滚动方法添加计时器来降低使用的处理能力可能不是一个好主意。视觉效果确实非常糟糕。
通过在滚动开始时隐藏滚动元素并使其在一段时间后滑入(在正确的位置),可以使整个Web浏览体验更好。滚动甚至也可以延迟检查。 这个解决方案效果很好。
$(document).ready(function() {
var element = $('.movable_div'),
originalY = element.offset().top;
element.css('position', 'relative');
$(window).on('scroll', function(event) {
var scrollTop = $(window).scrollTop();
element.hide();
element.stop(false, false).animate({
top: scrollTop < originalY
? 0
: scrollTop - originalY + 35
}, 2000,function(){element.slideDown(500,"swing");});
});
});
现场演示here