jQuery 如何检测滚动方向
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7154967/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to detect scroll direction
提问by Rik de Vos
I want to run a function when someone scrolls down on an element. Something like this:
当有人向下滚动元素时,我想运行一个函数。像这样的东西:
$('div').scrollDown(function(){ alert('down') });
$('div').scrollUp(function(){ alert('up') });
But those functions don't exist. Is there a solution to this problem? Awwwardsseem to be able to do it (logo in navbar changes depending on scroll direction). Unfortunately, the source code is compressed, so no luck there...
Thanks!!
但这些功能并不存在。这个问题有解决方案吗?Awwwards似乎能够做到(导航栏中的徽标会根据滚动方向而变化)。不幸的是,源代码被压缩,所以没有运气...
谢谢!
回答by Rik de Vos
I managed to figure it out in the end, so if anyone is looking for the answer:
最后我设法弄明白了,所以如果有人在寻找答案:
//Firefox
$('#elem').bind('DOMMouseScroll', function(e){
if(e.originalEvent.detail > 0) {
//scroll down
console.log('Down');
}else {
//scroll up
console.log('Up');
}
//prevent page fom scrolling
return false;
});
//IE, Opera, Safari
$('#elem').bind('mousewheel', function(e){
if(e.originalEvent.wheelDelta < 0) {
//scroll down
console.log('Down');
}else {
//scroll up
console.log('Up');
}
//prevent page fom scrolling
return false;
});
回答by honk31
Following example will listen to MOUSE scroll only, no touch nor trackpad scrolls.
以下示例将仅收听 MOUSE 滚动,不收听触摸或触控板滚动。
It uses jQuery.on()(As of jQuery 1.7, the .on() method is the preferred method for attaching event handlers to a document).
它使用jQuery.on()(从 jQuery 1.7 开始,.on() 方法是将事件处理程序附加到文档的首选方法)。
$('#elem').on( 'DOMMouseScroll mousewheel', function ( event ) {
if( event.originalEvent.detail > 0 || event.originalEvent.wheelDelta < 0 ) { //alternative options for wheelData: wheelDeltaX & wheelDeltaY
//scroll down
console.log('Down');
} else {
//scroll up
console.log('Up');
}
//prevent page fom scrolling
return false;
});
Works on all browsers.
适用于所有浏览器。
回答by Shikkediel
This one deserves an update - nowadays we have the wheel
event :
这个值得更新 - 现在我们有这样的wheel
活动:
$(function() {
$(window).on('wheel', function(e) {
var delta = e.originalEvent.deltaY;
if (delta > 0) $('body').text('down');
else $('body').text('up');
return false; // this line is only added so the whole page won't scroll in the demo
});
});
body {
font-size: 22px;
text-align: center;
color: white;
background: grey;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Support has been pretty good on modern browsers for quite a while already :
对现代浏览器的支持已经很长时间了:
- Chrome 31+
- Firefox 17+
- IE9+
- Opera 18+
- Safari 7+
- 铬 31+
- 火狐 17+
- IE9+
- 歌剧 18+
- Safari 7+
https://developer.mozilla.org/en-US/docs/Web/Events/wheel
https://developer.mozilla.org/en-US/docs/Web/Events/wheel
If deeper browser support is required, probably best to use mousewheel.js instead of messing about :
如果需要更深入的浏览器支持,最好使用 mousewheel.js 而不是搞乱:
https://plugins.jquery.com/mousewheel/
https://plugins.jquery.com/mousewheel/
$(function() {
$(window).mousewheel(function(turn, delta) {
if (delta > 0) $('body').text('up');
else $('body').text('down');
return false; // this line is only added so the whole page won't scroll in the demo
});
});
body {
font-size: 22px;
text-align: center;
color: white;
background: grey;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery-mousewheel/3.1.13/jquery.mousewheel.min.js"></script>
回答by Chemical Programmer
Existing Solution
现有解决方案
There could be 3 solutionfrom this posting and other stackoverflow article.
这篇文章和其他 stackoverflow 文章可能有3 个解决方案。
Solution 1
解决方案1
var lastScrollTop = 0;
$(window).on('scroll', function() {
st = $(this).scrollTop();
if(st < lastScrollTop) {
console.log('up 1');
}
else {
console.log('down 1');
}
lastScrollTop = st;
});
Solution 2
解决方案2
$('body').on('DOMMouseScroll', function(e){
if(e.originalEvent.detail < 0) {
console.log('up 2');
}
else {
console.log('down 2');
}
});
Solution 3
解决方案3
$('body').on('mousewheel', function(e){
if(e.originalEvent.wheelDelta > 0) {
console.log('up 3');
}
else {
console.log('down 3');
}
});
Multi Browser Test
多浏览器测试
I couldn't tested it on Safari
我无法在 Safari 上对其进行测试
chrome 42 (Win 7)
铬 42(赢 7)
- Solution 1
- Up : 1 event per 1 scroll
- Down : 1 event per 1 scroll
- Soltion 2
- Up : Not working
- Down : Not working
- Solution 3
- Up : 1 event per 1 scroll
- Down : 1 event per 1 scroll
- 解决方案1
- 向上:每 1 个滚动 1 个事件
- 向下:每 1 个滚动 1 个事件
- 解决方案 2
- 上:不工作
- 向下:不工作
- 解决方案3
- 向上:每 1 个滚动 1 个事件
- 向下:每 1 个滚动 1 个事件
Firefox 37 (Win 7)
火狐 37 (Win 7)
- Solution 1
- Up : 20 events per 1 scroll
- Down : 20 events per 1 scroll
- Soltion 2
- Up : Not working
- Down : 1 event per 1 scroll
- Solution 3
- Up : Not working
- Down : Not working
- 解决方案1
- 向上:每 1 个滚动 20 个事件
- 向下:每 1 个滚动 20 个事件
- 解决方案 2
- 上:不工作
- 向下:每 1 个滚动 1 个事件
- 解决方案3
- 上:不工作
- 向下:不工作
IE 11 (Win 8)
IE 11(赢8)
- Solution 1
- Up : 10 events per 1 scroll (side effect : down scroll occured at last)
- Down : 10 events per 1 scroll
- Soltion 2
- Up : Not working
- Down : Not working
- Solution 3
- Up : Not working
- Down : 1 event per 1 scroll
- 解决方案1
- 向上:每 1 个滚动 10 个事件(副作用:最后发生向下滚动)
- 向下:每 1 个滚动 10 个事件
- 解决方案 2
- 上:不工作
- 向下:不工作
- 解决方案3
- 上:不工作
- 向下:每 1 个滚动 1 个事件
IE 10 (Win 7)
IE 10(赢 7)
- Solution 1
- Up : 1 event per 1 scroll
- Down : 1 event per 1 scroll
- Soltion 2
- Up : Not working
- Down : Not working
- Solution 3
- Up : 1 event per 1 scroll
- Down : 1 event per 1 scroll
- 解决方案1
- 向上:每 1 个滚动 1 个事件
- 向下:每 1 个滚动 1 个事件
- 解决方案 2
- 上:不工作
- 向下:不工作
- 解决方案3
- 向上:每 1 个滚动 1 个事件
- 向下:每 1 个滚动 1 个事件
IE 9 (Win 7)
IE 9(赢 7)
- Solution 1
- Up : 1 event per 1 scroll
- Down : 1 event per 1 scroll
- Soltion 2
- Up : Not working
- Down : Not working
- Solution 3
- Up : 1 event per 1 scroll
- Down : 1 event per 1 scroll
- 解决方案1
- 向上:每 1 个滚动 1 个事件
- 向下:每 1 个滚动 1 个事件
- 解决方案 2
- 上:不工作
- 向下:不工作
- 解决方案3
- 向上:每 1 个滚动 1 个事件
- 向下:每 1 个滚动 1 个事件
IE 8 (Win 7)
IE 8(赢 7)
- Solution 1
- Up : 2 events per 1 scroll (side effect : down scroll occured at last)
- Down : 2~4 events per 1 scroll
- Soltion 2
- Up : Not working
- Down : Not working
- Solution 3
- Up : 1 event per 1 scroll
- Down : 1 event per 1 scroll
- 解决方案1
- 向上:每 1 次滚动 2 个事件(副作用:最后发生向下滚动)
- 向下:每 1 个滚动 2~4 个事件
- 解决方案 2
- 上:不工作
- 向下:不工作
- 解决方案3
- 向上:每 1 个滚动 1 个事件
- 向下:每 1 个滚动 1 个事件
Combined Solution
组合解决方案
I checked that side effect from IE 11 and IE 8 is come from
if else
statement. So, I replaced it withif else if
statement as following.
我检查了 IE 11 和 IE 8 的副作用来自
if else
声明。所以,我用if else if
下面的语句替换了它。
From the multi browser test, I decided to use Solution 3for common browsers and Solution 1for firefox and IE 11.
从多浏览器测试来看,我决定对常用浏览器使用解决方案3,对firefox和IE 11使用解决方案1。
I referred this answerto detect IE 11.
我参考了这个答案来检测 IE 11。
// Detect IE version
var iev=0;
var ieold = (/MSIE (\d+\.\d+);/.test(navigator.userAgent));
var trident = !!navigator.userAgent.match(/Trident\/7.0/);
var rv=navigator.userAgent.indexOf("rv:11.0");
if (ieold) iev=new Number(RegExp.);
if (navigator.appVersion.indexOf("MSIE 10") != -1) iev=10;
if (trident&&rv!=-1) iev=11;
// Firefox or IE 11
if(typeof InstallTrigger !== 'undefined' || iev == 11) {
var lastScrollTop = 0;
$(window).on('scroll', function() {
st = $(this).scrollTop();
if(st < lastScrollTop) {
console.log('Up');
}
else if(st > lastScrollTop) {
console.log('Down');
}
lastScrollTop = st;
});
}
// Other browsers
else {
$('body').on('mousewheel', function(e){
if(e.originalEvent.wheelDelta > 0) {
console.log('Up');
}
else if(e.originalEvent.wheelDelta < 0) {
console.log('Down');
}
});
}
回答by AlienWebguy
$(function(){
var _top = $(window).scrollTop();
var _direction;
$(window).scroll(function(){
var _cur_top = $(window).scrollTop();
if(_top < _cur_top)
{
_direction = 'down';
}
else
{
_direction = 'up';
}
_top = _cur_top;
console.log(_direction);
});
});
回答by Erick Petrucelli
Here is a sampleshowing an easy way to do it. The script is:
这是一个示例,展示了一种简单的方法。脚本是:
$(function() {
var _t = $("#container").scrollTop();
$("#container").scroll(function() {
var _n = $("#container").scrollTop();
if (_n > _t) {
$("#target").text("Down");
} else {
$("#target").text("Up");
}
_t = _n;
});
});
The #container
is your div id
. The #target
is just to see it working. Change to what you want when up or when down.
这#container
是你的 div id
。该#target
是刚才看到它的工作。上升或下降时更改为您想要的。
EDIT
编辑
The OP didn't say before, but since he's using a div with overflow: hidden
, scrolling doesn't occur, then the script to detect the scroll is the least of it. Well, how to detect something that does not happen?!
OP 之前没有说,但由于他使用 div 和overflow: hidden
,滚动不会发生,那么检测滚动的脚本是最少的。那么,如何检测不会发生的事情?!
So, the OP himself posted the link with what he wants, so why not use that library? http://cdn.jquerytools.org/1.2.5/full/jquery.tools.min.js.
所以,OP 自己发布了他想要的链接,那么为什么不使用那个库呢?http://cdn.jquerytools.org/1.2.5/full/jquery.tools.min.js。
The call is just:
电话只是:
$(function() {
$(".scrollable").scrollable({ vertical: true, mousewheel: true });
});
回答by Jithin U. Ahmed
var mousewheelevt = (/Firefox/i.test(navigator.userAgent)) ? "DOMMouseScroll" : "mousewheel" //FF doesn't recognize mousewheel as of FF3.x
$(document).bind(mousewheelevt,
function(e)
{
var evt = window.event || e //equalize event object
evt = evt.originalEvent ? evt.originalEvent : evt; //convert to originalEvent if possible
var delta = evt.detail ? evt.detail*(-40) : evt.wheelDelta //check for detail first, because it is used by Opera and FF
if(delta > 0)
{
scrollup();
}
else
{
scrolldown();
}
}
);
回答by user122293
You can use this simple plugin to add scrollUp
and scrollDown
to your jQuery
您可以使用这个简单的插件来添加scrollUp
和添加scrollDown
到您的 jQuery
https://github.com/phpust/JQueryScrollDetector
https://github.com/phpust/JQueryScrollDetector
var lastScrollTop = 0;
var action = "stopped";
var timeout = 100;
// Scroll end detector:
$.fn.scrollEnd = function(callback, timeout) {
$(this).scroll(function(){
// get current scroll top
var st = $(this).scrollTop();
var $this = $(this);
// fix for page loads
if (lastScrollTop !=0 )
{
// if it's scroll up
if (st < lastScrollTop){
action = "scrollUp";
}
// else if it's scroll down
else if (st > lastScrollTop){
action = "scrollDown";
}
}
// set the current scroll as last scroll top
lastScrollTop = st;
// check if scrollTimeout is set then clear it
if ($this.data('scrollTimeout')) {
clearTimeout($this.data('scrollTimeout'));
}
// wait until timeout done to overwrite scrolls output
$this.data('scrollTimeout', setTimeout(callback,timeout));
});
};
$(window).scrollEnd(function(){
if(action!="stopped"){
//call the event listener attached to obj.
$(document).trigger(action);
}
}, timeout);