ChatGPT解决这个技术问题 Extra ChatGPT

检测滚动方向

所以我尝试使用 JavaScript on scroll 来调用函数。但我想知道是否可以在不使用 jQuery 的情况下检测滚动的方向。如果没有,那么有什么解决方法吗?

我正在考虑只放置一个“顶部”按钮,但如果可以的话,我想避免这种情况。

我现在刚刚尝试使用此代码,但它不起作用:

if document.body.scrollTop <= 0 {
    alert ("scrolling down")
} else {
    alert ("scrolling up")
}
这是事件的 wheelDelta。完全不是跨浏览器。请参阅phrogz.net/js/wheeldelta.html
嗯,不是我要找的东西,但感谢您的帮助:P 还有其他建议吗?

L
Littm

可以通过存储之前的 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 {
      // upscroll code
   }
   lastScrollTop = st <= 0 ? 0 : st; // For Mobile or negative scrolling
}, false);

lastScrollTop 初始化为 pageYOffset || 会更安全scrollTop 而不是假设为 0
完全同意 !!谢谢@EdBallot。我们应该在 window.onload 事件上进行相同的初始化。
@Prateek 感谢您的回答,但它对我不起作用......我正在尝试在我的使用 Tumult Hype 构建的 web 应用程序中“改变场景”。
我在回答中添加了一些评论,请检查。我猜你正在使用“element.addEventListener”。
@Prateek 仍然没什么我害怕的。这可能与我在页面加载时运行它有关吗?这是一个屏幕截图:i.imgur.com/Q0H0T4s.png
I
IT VLOG

捕获所有滚动事件(触摸和滚轮)的简单方法

window.onscroll = function(e) {
  // print "false" if direction is down and "true" if up
  console.log(this.oldScroll > this.scrollY);
  this.oldScroll = this.scrollY;
}

欢迎来到 SO,如果您在答案中添加描述,这可能对 OP 和其他人更有帮助。
C
Community

使用它来查找滚动方向。这只是为了找到垂直滚动的方向。支持所有跨浏览器。

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

Example


这很好,但似乎只适用于使用滚轮
来自 MDN webdocs:注意:不要将滚轮事件与滚动事件混淆。 Wheel 事件的默认操作是特定于实现的,并且不一定调度滚动事件。即使是这样,wheel 事件中的 delta* 值也不一定反映内容的滚动方向。因此,不要依赖 wheel 事件的 delta* 属性来获取滚动方向。而是在滚动事件中检测目标的 scrollLeft 和 scrollTop 的值变化。 developer.mozilla.org/en-US/docs/Web/API/Element/wheel_event
这个很好(与 scroll 事件相比),因为它也会在到达滚动位置的结尾或开始后触发 - 有时您可能想要触发一些特定操作以“滚动”到元素的末尾。
谢谢!在“固定”定位部分非常有用!
d
davecar21

你可以尝试这样做。

函数 scrollDetect(){ var lastScroll = 0; window.onscroll = function() { 让 currentScroll = document.documentElement.scrollTop || document.body.scrollTop; // 获取当前滚动值 if (currentScroll > 0 && lastScroll <= currentScroll){ lastScroll = currentScroll; document.getElementById("scrollLoc").innerHTML = "向下滚动"; }else{ lastScroll = currentScroll; document.getElementById("scrollLoc").innerHTML = "向上滚动"; } }; } 滚动检测(); html,body{ 高度:100%;宽度:100%;边距:0;填充:0; } .cont{ 高度:100%;宽度:100%; } .item{ 边距:0;填充:0;高度:100%;宽度:100%;背景:#ffad33; } .red{ 背景:红色; } p{ 位置:固定;字体大小:25px;前5%;左:5%; }

0


这对我来说效果不佳。当我向上滚动到某个特定高度时,它会向下显示
t
thewebjackal

初始化一个 oldValue 通过监听事件获取 newValue 从结果中减去两者 得出结论 用 newValue 更新 oldValue

// 初始化

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;
});

E
Emmanual

这是对 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;
});});

感谢您的提示...这似乎与 IE“平滑滚动”选项有关
G
Ganesh Sundaram

这个简单的代码可以工作:检查控制台的结果。

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 都会强制元素的布局(在本例中为整个主体)。因此,最好在每个滚动事件中调用一次并缓存结果......
t
theUtherSide

虽然公认的答案有效,但值得注意的是,这将以很高的速度触发。这可能会导致计算成本高昂的操作出现性能问题。

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");
    }
});


I
Igal S.

您可以使用 document.documentElement.scrollTop 获取滚动条位置。然后只需将其与之前的位置进行比较即可。


好的,我还能在传统上不允许滚动的网站上使用它吗(即它适合浏览器 100% 的宽度和高度。谢谢
n
notapatch

我个人使用此代码来检测 javascript 中的滚动方向...只需定义一个变量来存储 lastscrollvalue 然后使用这个 if&else

let lastscrollvalue;

function headeronscroll() {

    // document on which scroll event will occur
    var a = document.querySelector('.refcontainer'); 

    if (lastscrollvalue == undefined) {

        lastscrollvalue = a.scrollTop;

        // sets lastscrollvalue
    } else if (a.scrollTop > lastscrollvalue) {

        // downscroll rules will be here
        lastscrollvalue = a.scrollTop;

    } else if (a.scrollTop < lastscrollvalue) {

        // upscroll rules will be here
        lastscrollvalue = a.scrollTop;

    }
}

这太棒了,它适用于任何元素,不仅是窗口
K
Kaung Khant Zaw

如果有人希望通过 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)

J
Justin Golden

修改 Prateek 的回答,如果 lastScrollTop 没有变化,那么它将是水平滚动(x 方向溢出,可以通过鼠标使用水平滚动条或使用滚轮 + shift 来使用。

const containerElm = document.getElementById("container");

let lastScrollTop = containerElm.scrollTop;

containerElm.addEventListener("scroll", (evt) => {
  const st = containerElm.scrollTop;

  if (st > lastScrollTop) {
    console.log("down scroll");
  } else if (st < lastScrollTop) {
    console.log("up scroll");
  } else {
    console.log("horizontal scroll");
  }

  lastScrollTop = Math.max(st, 0); // For mobile or negative scrolling
});

M
Maciek Rek

这似乎工作正常。

document.addEventListener('DOMContentLoaded', () => {

    var scrollDirectionDown;
    scrollDirectionDown = true;

    window.addEventListener('scroll', () => {

        if (this.oldScroll > this.scrollY) {
            scrollDirectionDown = false;
        } else {
            scrollDirectionDown = true;
        }
        this.oldScroll = this.scrollY;


        // test
        if (scrollDirectionDown) {
            console.log('scrolling down');
        } else {
            console.log('scrolling up');
        }



    });
});