jQuery/JavaScript:检测滚动方向 - 代码结构问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15264632/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 00:06:23  来源:igfitidea点击:

jQuery/JavaScript: Detecting scroll direction - code structure issue

javascriptjqueryscrollreturncode-structure

提问by Sven

I need to detect the direction in that a user scrolls - "up" or "down". Based on the code found in this answer: How can I determine the direction of a jQuery scroll event?

我需要检测用户滚动的方向 - “向上”或“向下”。基于此答案中的代码:如何确定 jQuery 滚动事件的方向?

I tried to wrap it in a function so it's a bit more differentiated - but unfortunately, it's not working. I think it has something to do with how I return the value, but the direction is always "up". Being fairly new to JavaScript I am having problems solving this issue.

我试图将它包装在一个函数中,因此它更具差异化 - 但不幸的是,它不起作用。我认为这与我如何返回值有关,但方向总是“向上”。作为 JavaScript 的新手,我在解决这个问题时遇到了问题。

Here is the code:

这是代码:

$(document).ready(function () {

    'use strict';

    var lastScrollTop = 0,
        st,
        direction;

    function detectDirection() {

        st = window.pageYOffset;

        if (st > lastScrollTop) {
            direction = "down";
        } else {
            direction = "up";
        }

        lastScrollTop = st;

        return  direction;

    }

    $(window).bind('scroll', function() {

        detectDirection();
        console.log(detectDirection());

    });

});

And I've also set up a Fiddle.

而且我还设置了一个Fiddle

Could you please help me spotting where the problem is?

你能帮我找出问题所在吗?

采纳答案by Barmar

$(window).bind('scroll', function() {

    var dir = detectDirection();
    console.log(dir);

});

You were calling detectDirection()twice during each scroll event. The first one detected the correct direction, but the second one just saw it in the same place, so it returned "up", and that's what you logged.

detectDirection()在每个滚动事件期间都调用了两次。第一个检测到正确的方向,但第二个只是在同一个地方看到它,所以它返回“向上”,这就是你记录的内容。

回答by vol7ron

See what you get with this:

看看你得到了什么:

if (st > lastScrollTop) {
    direction = "down";
} else if (st < lastScrollTop ){
    direction = "up";
} else {
    direction = "static";
}

In addition to what Barmar stated, you could get rid of the line (the call) above the console output and just keep:

除了 Barmar 所说的内容之外,您还可以去掉控制台输出上方的行(调用)并保留:

console.log(detectDirection());

回答by Samuel Mburu

The code as it is will not work since we never update the lastScrollTop, here is the working code...

由于我们从不更新 lastScrollTop,因此代码无法正常工作,这是工作代码......

$(function(config){
    var lastScrollTop = 0, // setting initial scrolltop as top of page
        direction; // direction of scroll 1)up -1)down 0)static

    function detectDirection() {
        // current scrollTop can't be cached or in the local global scope
        var st = window.pageYOffset;

        if (st > lastScrollTop) {
            // scrolling down
            direction = -1;
        } else if (st < lastScrollTop ){
            // scrolling up
            direction = 1;
        } else {
            // static
            direction = 0;
        }

        // updated lastscrolltop with new current top
        lastScrollTop = st;

        // return the direction
        return direction;
    }`

I used 0 as static/ 1 as scrolling up/ -1 as scrolling down

我使用 0 作为静态/ 1 作为向上滚动/ -1 作为向下滚动

Hope that helps someone.

希望能帮助某人。

回答by SwankyLegg

I'm providing a new answer because while BarMar's answer solves your immediate problem, the solution doesn't help you structure the code in a way that will enable you to do two things.

我提供了一个新的答案,因为虽然 BarMar 的答案解决了您眼前的问题,但该解决方案并不能帮助您以一种使您能够做两件事的方式构建代码。

  1. Scope the scroll object more broadly, allowing you to access its attributes elsewhere. This would allow you to do something if the scroll position is a certain value.

  2. Improve the performance of the scrolling.

    // Your current functionality
    $(document).ready(function() {
      var scroll = {
        down: true,
        pos: 0
      };
      var scrollPos;
    
      var detectDirection = function() {
        scrollPos = window.pageYOffset;
    
        if (scrollPos > scroll.pos) {
          scroll.down = true;
        } else {
          scroll.down = false;
        }
    
        scroll.pos = scrollPos;
      };
    
      $(window).on('optimizedScroll', function() {
        detectDirection();
    
        // Do something based on scroll direction
        if (scroll.down == true) {
          // fooFunction();
        } else {
          // barFunction();
        }
    
        // Do something based on scroll position,
        // where scrollTrigger is a number
        if (scroll.pos > scrollTrigger) {
          // bazFunction();
        }
      });
    });
    
    // Improve scroll performance
    (function() {
        var throttle = function(type, name, obj) {
          var obj = obj || window;
          var running = false;
          var func = function() {
            if (running) {
              return;
            }
            running = true;
            requestAnimationFrame(function() {
            obj.dispatchEvent(new CustomEvent(name));
              running = false;
            });
          };
          obj.addEventListener(type, func);
        };
    
        throttle('scroll', 'optimizedScroll');
    })();
    
  1. 范围更广泛的滚动对象,允许您在其他地方访问其属性。如果滚动位置是某个值,这将允许您执行某些操作。

  2. 提高滚动的性能。

    // Your current functionality
    $(document).ready(function() {
      var scroll = {
        down: true,
        pos: 0
      };
      var scrollPos;
    
      var detectDirection = function() {
        scrollPos = window.pageYOffset;
    
        if (scrollPos > scroll.pos) {
          scroll.down = true;
        } else {
          scroll.down = false;
        }
    
        scroll.pos = scrollPos;
      };
    
      $(window).on('optimizedScroll', function() {
        detectDirection();
    
        // Do something based on scroll direction
        if (scroll.down == true) {
          // fooFunction();
        } else {
          // barFunction();
        }
    
        // Do something based on scroll position,
        // where scrollTrigger is a number
        if (scroll.pos > scrollTrigger) {
          // bazFunction();
        }
      });
    });
    
    // Improve scroll performance
    (function() {
        var throttle = function(type, name, obj) {
          var obj = obj || window;
          var running = false;
          var func = function() {
            if (running) {
              return;
            }
            running = true;
            requestAnimationFrame(function() {
            obj.dispatchEvent(new CustomEvent(name));
              running = false;
            });
          };
          obj.addEventListener(type, func);
        };
    
        throttle('scroll', 'optimizedScroll');
    })();
    

Rather than using .bind(), you should use .on(), as per the jQuery .bind() documentation.

根据jQuery .bind() 文档,您应该使用 .on() 而不是使用 .bind() 。

The Immediately Invoked Function Expression (IIFE)to improve the scroll performance comes from the MDN documentation for the scroll event.

用于提高滚动性能的立即调用函数表达式 (IIFE)来自滚动事件MDN 文档