jQuery滚动事件:如何确定以像素为单位滚动的数量(滚动增量)?
我有这个事件:
$(window).scroll(function(e){ console.log(e); })
我想知道,我有多少像素滚动值,因为我认为,滚动值取决于窗口大小和屏幕分辨率。
function参数e
不包含此信息。
我可以在每次滚动后存储$(window).scrollTop()
并计算差异,但我可以采用不同的方式吗?
“滚动值”不依赖于窗口大小或屏幕分辨率。 “滚动值”只是滚动的像素数。
但是,您是否能够滚动,并且可以滚动的数量取决于容器的可用空间和容器内容的大小(在这种情况下,容器是document.documentElement
或document.body
对于旧浏览器)。
scroll
事件不包含此信息,这是正确的。 它不提供delta
属性来指示滚动的像素数。 这适用于本机scroll
事件和jQuery scroll
事件。 这似乎是一个有用的function,类似于mousewheel
事件如何为X和Y delta提供属性。
我不知道,也不会推测,为什么权力没有为scroll
提供delta
属性,但这超出了这个问题的范围(随意发布一个单独的问题)。
您正在使用将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'; }
scrollTop: 0px, scrollLeft: 0px
要确定滚动的像素数量,您必须记住, 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); });
通过这种方式,您可以在滚动后获得滚动一秒的数量(这是可调整的,但您必须记住,今天如此流行的平滑滚动有一些用完的时间,而您不希望在完全停止之前触发) 。
另一种方法呢? 是的,可能,使用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); });
通过向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");}); }); });
现场演示