admin管理员组文章数量:1126097
I'm looking for something to this effect:
$(window).scroll(function(event){
if (/* magic code*/ ){
// upscroll code
} else {
// downscroll code
}
});
Any ideas?
I'm looking for something to this effect:
$(window).scroll(function(event){
if (/* magic code*/ ){
// upscroll code
} else {
// downscroll code
}
});
Any ideas?
Share Improve this question edited Feb 3, 2013 at 5:33 ThinkingStiff 65.3k30 gold badges147 silver badges241 bronze badges asked Dec 1, 2010 at 16:57 ZachZach 19.1k18 gold badges61 silver badges68 bronze badges 2 |25 Answers
Reset to default 758Check current scrollTop
vs previous scrollTop
var lastScrollTop = 0;
$(window).scroll(function(event){
var st = $(this).scrollTop();
if (st > lastScrollTop){
// downscroll code
} else {
// upscroll code
}
lastScrollTop = st;
});
You can do it without having to keep track of the previous scroll top, as all the other examples require:
$(window).bind('mousewheel', function(event) {
if (event.originalEvent.wheelDelta >= 0) {
console.log('Scroll up');
}
else {
console.log('Scroll down');
}
});
I am not an expert on this so feel free to research it further, but it appears that when you use $(element).scroll
, the event being listened for is a 'scroll' event.
But if you specifically listen for a mousewheel
event by using bind, the originalEvent
attribute of the event parameter to your callback contains different information. Part of that information is wheelDelta
. If it's positive, you moved the mousewheel up. If it's negative, you moved the mousewheel down.
My guess is that mousewheel
events will fire when the mouse wheel turns, even if the page does not scroll; a case in which 'scroll' events probably are not fired. If you want, you can call event.preventDefault()
at the bottom of your callback to prevent the page from scrolling, and so that you can use the mousewheel event for something other than a page scroll, like some type of zoom functionality.
Store the previous scroll location, then see if the new one is greater than or less than that.
Here's a way to avoid any global variables (fiddle available here):
(function () {
var previousScroll = 0;
$(window).scroll(function(){
var currentScroll = $(this).scrollTop();
if (currentScroll > previousScroll){
alert('down');
} else {
alert('up');
}
previousScroll = currentScroll;
});
}()); //run this anonymous function immediately
Existing Solution
There could be 3 solution from this posting and other answer.
Solution 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
$('body').on('DOMMouseScroll', function(e){
if(e.originalEvent.detail < 0) {
console.log('up 2');
}
else {
console.log('down 2');
}
});
Solution 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
chrome 42 (Win 7)
- Solution 1
- Up : 1 event per 1 scroll
- Down : 1 event per 1 scroll
- Solution 2
- Up : Not working
- Down : Not working
- Solution 3
- Up : 1 event per 1 scroll
- Down : 1 event per 1 scroll
Firefox 37 (Win 7)
- Solution 1
- Up : 20 events per 1 scroll
- Down : 20 events per 1 scroll
- Solution 2
- Up : Not working
- Down : 1 event per 1 scroll
- Solution 3
- Up : Not working
- Down : Not working
IE 11 (Win 8)
- Solution 1
- Up : 10 events per 1 scroll (side effect : down scroll occured at last)
- Down : 10 events per 1 scroll
- Solution 2
- Up : Not working
- Down : Not working
- Solution 3
- Up : Not working
- Down : 1 event per 1 scroll
IE 10 (Win 7)
- Solution 1
- Up : 1 event per 1 scroll
- Down : 1 event per 1 scroll
- Solution 2
- Up : Not working
- Down : Not working
- Solution 3
- Up : 1 event per 1 scroll
- Down : 1 event per 1 scroll
IE 9 (Win 7)
- Solution 1
- Up : 1 event per 1 scroll
- Down : 1 event per 1 scroll
- Solution 2
- Up : Not working
- Down : Not working
- Solution 3
- Up : 1 event per 1 scroll
- Down : 1 event per 1 scroll
IE 8 (Win 7)
- Solution 1
- Up : 2 events per 1 scroll (side effect : down scroll occured at last)
- Down : 2~4 events per 1 scroll
- Solution 2
- Up : Not working
- Down : Not working
- Solution 3
- Up : 1 event per 1 scroll
- Down : 1 event per 1 scroll
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.
From the multi browser test, I decided to use Solution 3 for common browsers and Solution 1 for firefox and IE 11.
I referred this answer to detect 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.$1);
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');
}
});
}
I understand there has already been an accepted answer, but wanted to post what I am using in case it can help anyone. I get the direction like cliphex
with the mousewheel event but with support for Firefox. It's useful doing it this way in case you are doing something like locking scroll and can't get the current scroll top.
See a live version here.
$(window).on('mousewheel DOMMouseScroll', function (e) {
var direction = (function () {
var delta = (e.type === 'DOMMouseScroll' ?
e.originalEvent.detail * -40 :
e.originalEvent.wheelDelta);
return delta > 0 ? 0 : 1;
}());
if(direction === 1) {
// scroll down
}
if(direction === 0) {
// scroll up
}
});
Scroll Event
The scroll event behaves oddly in FF (it is fired a lot of times because of the smoothness scrolling) but it works.
Note: The scroll event actually is fired when dragging the scroll bar, using cursor keys or mousewheel.
//creates an element to print the scroll position
$("<p id='test'>").appendTo("body").css({
padding: "5px 7px",
background: "#e9e9e9",
position: "fixed",
bottom: "15px",
left: "35px"
});
//binds the "scroll" event
$(window).scroll(function (e) {
var target = e.currentTarget,
self = $(target),
scrollTop = window.pageYOffset || target.scrollTop,
lastScrollTop = self.data("lastScrollTop") || 0,
scrollHeight = target.scrollHeight || document.body.scrollHeight,
scrollText = "";
if (scrollTop > lastScrollTop) {
scrollText = "<b>scroll down</b>";
} else {
scrollText = "<b>scroll up</b>";
}
$("#test").html(scrollText +
"<br>innerHeight: " + self.innerHeight() +
"<br>scrollHeight: " + scrollHeight +
"<br>scrollTop: " + scrollTop +
"<br>lastScrollTop: " + lastScrollTop);
if (scrollHeight - scrollTop === self.innerHeight()) {
console.log("► End of scroll");
}
//saves the current scrollTop
self.data("lastScrollTop", scrollTop);
});
Wheel Event
You also may take a look at MDN, it exposes a great information about the Wheel Event.
Note: The wheel event is fired only when using the mousewheel; cursor keys and dragging the scroll bar does not fire the event.
I read the document and the example: Listening to this event across browser
and after some tests with FF, IE, chrome, safari, I ended up with this snippet:
//creates an element to print the scroll position
$("<p id='test'>").appendTo("body").css({
padding: "5px 7px",
background: "#e9e9e9",
position: "fixed",
bottom: "15px",
left: "15px"
});
//attach the "wheel" event if it is supported, otherwise "mousewheel" event is used
$("html").on(("onwheel" in document.createElement("div") ? "wheel" : "mousewheel"), function (e) {
var evt = e.originalEvent || e;
//this is what really matters
var deltaY = evt.deltaY || (-1 / 40 * evt.wheelDelta), //wheel || mousewheel
scrollTop = $(this).scrollTop() || $("body").scrollTop(), //fix safari
scrollText = "";
if (deltaY > 0) {
scrollText = "<b>scroll down</b>";
} else {
scrollText = "<b>scroll up</b>";
}
//console.log("Event: ", evt);
$("#test").html(scrollText +
"<br>clientHeight: " + this.clientHeight +
"<br>scrollHeight: " + this.scrollHeight +
"<br>scrollTop: " + scrollTop +
"<br>deltaY: " + deltaY);
});
In case you just want to know if you scroll up or down using a pointer device (mouse or track pad) you can use the deltaY property of the wheel
event.
$('.container').on('wheel', function(event) {
if (event.originalEvent.deltaY > 0) {
$('.result').append('Scrolled down!<br>');
} else {
$('.result').append('Scrolled up!<br>');
}
});
.container {
height: 200px;
width: 400px;
margin: 20px;
border: 1px solid black;
overflow-y: auto;
}
.content {
height: 300px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="content">
Scroll me!
</div>
</div>
<div class="result">
<p>Action:</p>
</div>
Update 2021-04-07
Bobort in a comment (thanks!) pointed to the new note added in the wheel documentation:
Don't confuse the wheel event with the scroll event. The default action of a wheel event is implementation-specific, and doesn't necessarily dispatch a scroll event. Even when it does, the delta* values in the wheel event don't necessarily reflect the content's scrolling direction. Therefore, do not rely on the wheel event's delta* properties to get the scrolling direction. Instead, detect value changes of scrollLeft and scrollTop of the target in the scroll event.
However, the example given in the documentation uses delta to scale, which implies a scroll up for zooming out and scroll down for zooming in.
The code below worked for me in different browsers to detect direction, but given that note, use it at your own risk.
Original answer
Since bind
has been deprecated on v3 ("superseded by on
") and wheel
is now supported, forget wheelDelta
:
$(window).on('wheel', function(e) {
if (e.originalEvent.deltaY > 0) {
console.log('down');
} else if (e.originalEvent.deltaY < 0) {
console.log('up');
} else if (e.originalEvent.deltaX > 0) {
console.log('right');
} else if (e.originalEvent.deltaX < 0) {
console.log('left');
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1 style="white-space:nowrap;overflow:scroll">
本文标签:
javascriptHow can I determine the direction of a jQuery scroll eventStack Overflow
版权声明:本文标题:javascript - How can I determine the direction of a jQuery scroll event? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人,
转载请联系作者并注明出处:http://www.betaflare.com/web/1736682254a1947478.html,
本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
wheel
event these days : stackoverflow.com/a/33334461/3168107. – Shikkediel Commented Oct 29, 2015 at 11:41