我正在尝试使用JavaScript的on scroll
调用函数。但是我想知道是否可以在不使用jQuery的情况下检测滚动的方向。如果不行,那么有没有什么解决方法?
我考虑只放置一个“返回顶部”按钮,但如果可能的话,我想避免这样做。
我已经尝试了以下代码,但它没有起作用:
if document.body.scrollTop <= 0 {
alert ("scrolling down")
} else {
alert ("scrolling up")
}
我正在尝试使用JavaScript的on scroll
调用函数。但是我想知道是否可以在不使用jQuery的情况下检测滚动的方向。如果不行,那么有没有什么解决方法?
我考虑只放置一个“返回顶部”按钮,但如果可能的话,我想避免这样做。
我已经尝试了以下代码,但它没有起作用:
if document.body.scrollTop <= 0 {
alert ("scrolling down")
} else {
alert ("scrolling up")
}
通过存储先前的 scrollTop
值并将当前的 scrollTop 值与之进行比较,可以检测到它。
JavaScript:
var lastScrollTop = 0;
// element should be replaced with the actual target element on which you have applied scroll, use window in case of no target element.
element.addEventListener("scroll", function(){ // or window.addEventListener("scroll"....
var st = window.pageYOffset || document.documentElement.scrollTop; // Credits: "https://github.com/qeremy/so/blob/master/so.dom.js#L426"
if (st > lastScrollTop) {
// downscroll code
} else if (st < lastScrollTop) {
// upscroll code
} // else was horizontal scroll
lastScrollTop = st <= 0 ? 0 : st; // For Mobile or negative scrolling
}, false);
lastScrollTop
的初始化设置为 pageYOffset || scrollTop
,而不是假定为 0,这样会更安全。 - Ed Ballot<= 0
的测试处理了这种情况。另一种类似的情况可能会在另一端出现。 - Jake捕获所有滚动事件(触摸和鼠标滚轮)的简单方法
window.onscroll = function(e) {
// print "false" if direction is down and "true" if up
console.log(this.oldScroll > this.scrollY);
this.oldScroll = this.scrollY;
}
使用此功能查找滚动方向。仅用于查找垂直滚动的方向。支持所有浏览器。
var scrollableElement = document.body; //document.getElementById('scrollableElement');
scrollableElement.addEventListener('wheel', checkScrollDirection);
function checkScrollDirection(event) {
if (checkScrollDirectionIsUp(event)) {
console.log('UP');
} else {
console.log('Down');
}
}
function checkScrollDirectionIsUp(event) {
if (event.wheelDelta) {
return event.wheelDelta > 0;
}
return event.deltaY < 0;
}
你可以尝试这样做。
function scrollDetect(){
var lastScroll = 0;
window.onscroll = function() {
let currentScroll = document.documentElement.scrollTop || document.body.scrollTop; // Get Current Scroll Value
if (currentScroll > 0 && lastScroll <= currentScroll){
lastScroll = currentScroll;
document.getElementById("scrollLoc").innerHTML = "Scrolling DOWN";
}else{
lastScroll = currentScroll;
document.getElementById("scrollLoc").innerHTML = "Scrolling UP";
}
};
}
scrollDetect();
html,body{
height:100%;
width:100%;
margin:0;
padding:0;
}
.cont{
height:100%;
width:100%;
}
.item{
margin:0;
padding:0;
height:100%;
width:100%;
background: #ffad33;
}
.red{
background: red;
}
p{
position:fixed;
font-size:25px;
top:5%;
left:5%;
}
<div class="cont">
<div class="item"></div>
<div class="item red"></div>
<p id="scrollLoc">0</p>
</div>
// 初始化
let oldValue = 0;
//监听事件
window.addEventListener('scroll', function(e){
// Get the new Value
newValue = window.pageYOffset;
//Subtract the two and conclude
if(oldValue - newValue < 0){
console.log("Up");
} else if(oldValue - newValue > 0){
console.log("Down");
}
// Update the old value
oldValue = newValue;
});
尽管已接受的答案有效,但值得注意的是,这将以高速率触发。这可能会对计算密集型操作造成性能问题。
MDN的建议是限制事件频率。以下是他们示例的修改版本,增强了检测滚动方向的功能。
修改自:https://developer.mozilla.org/en-US/docs/Web/API/Document/scroll_event
// ## function declaration
function scrollEventThrottle(fn) {
let last_known_scroll_position = 0;
let ticking = false;
window.addEventListener("scroll", function () {
let previous_known_scroll_position = last_known_scroll_position;
last_known_scroll_position = window.scrollY;
if (!ticking) {
window.requestAnimationFrame(function () {
fn(last_known_scroll_position, previous_known_scroll_position);
ticking = false;
});
ticking = true;
}
});
}
// ## function invocation
scrollEventThrottle((scrollPos, previousScrollPos) => {
if (previousScrollPos > scrollPos) {
console.log("going up");
} else {
console.log("going down");
}
});
这是对prateek回答的补充。在IE浏览器中,代码似乎存在一些问题,所以我决定稍微修改一下它,没有什么花哨的东西(只是添加了另一个条件)。
$('document').ready(function() {
var lastScrollTop = 0;
$(window).scroll(function(event){
var st = $(this).scrollTop();
if (st > lastScrollTop){
console.log("down")
}
else if(st == lastScrollTop)
{
//do nothing
//In IE this is an important condition because there seems to be some instances where the last scrollTop is equal to the new one
}
else {
console.log("up")
}
lastScrollTop = st;
});});
下面这段简单的代码是可行的:在控制台中查看结果。
let scroll_position = 0;
let scroll_direction;
window.addEventListener('scroll', function(e){
scroll_direction = (document.body.getBoundingClientRect()).top > scroll_position ? 'up' : 'down';
scroll_position = (document.body.getBoundingClientRect()).top;
console.log(scroll_direction);
});
getBoundingClientRect
会在每次调用时强制对元素(在本例中为整个 body)进行布局。因此,最好在每次滚动事件中仅调用一次并缓存结果... - Heretic Monkey如果有人想用 React hooks
来实现它
const [scrollStatus, setScrollStatus] = useState({
scrollDirection: null,
scrollPos: 0,
});
useEffect(() => {
window.addEventListener("scroll", handleScrollDocument);
return () => window.removeEventListener("scroll", handleScrollDocument);
}, []);
function handleScrollDocument() {
setScrollStatus((prev) => { // to get 'previous' value of state
return {
scrollDirection:
document.body.getBoundingClientRect().top > prev.scrollPos
? "up"
: "down",
scrollPos: document.body.getBoundingClientRect().top,
};
});
}
console.log(scrollStatus.scrollDirection)
document.documentElement.scrollTop
获取滚动条位置。然后,只需要将其与先前的位置进行比较即可。
wheelDelta
。在不同浏览器中可能会有差异。请参考 http://phrogz.net/js/wheeldelta.html。 - marekful