【亲测!3种方法】JS判断滚动条上滚下滚
作者:admin 时间:2022-4-25 7:7:26 浏览:本文通过本人亲自测试代码可用,给大家分享3种方法,JS判断滚动条上滚下滚。这3种方法出来的效果是有所区别的,内文会详细介绍。
通过代码测试的浏览器有:Chrome、Firefox、IE11、安卓手机UC。
代码调试花了不少时间,网上流传的的代码大多是不可用的,大部分人都是复制粘贴无经测试。
1、判断滚动条上滚下滚(普通版)
 
首先介绍的是第一种方法,判断滚动条上滚下滚(普通版),说是普通版,其实是与后面的加强版区分而已。加强版是是在普通版代码的基础上做了一些改进。
普通版判断滚动条上滚下滚,是时时刻刻判断滚动条上滚下滚,比如上滚就返回true,下滚就返回false。看上面的图示,滚动条上滚下滚时控制台输出“down”和“up”前面数字的快速变化,可以看出代码执行的次数是非常之多的。
JS代码如下:
function scroll( fn ) {
    var beforeScrollTop = $(this).scrollTop(),
    fn = fn || function() {};
    window.addEventListener("scroll", function() {
        var afterScrollTop = $(this).scrollTop(),
            delta = afterScrollTop - beforeScrollTop;
        if( delta === 0 ) return false;
        fn( delta > 0 ? "down" : "up" );
        beforeScrollTop = afterScrollTop;
    }, false);
}
//第一种写法
scroll(function(direction) {
    console.log(direction);  
});
  
//第二种写法执行完事件后的回调函数
/*
    function fn(direction) {
        console.log(direction); //down or up   
    };
    window.onscroll=function(){
        scroll( fn );
    }
*/代码解释:
上面两种写法都可以用,亲测!
代码实现思路是获得滚动条滚动前后两次的位置,通过对比判断上滚还是下滚。$(this).scrollTop() 是获得滚动条位置的代码,注意,这个是滚动条顶部相对于文档的位置而不是相对于窗口的位置。请看一图理解$(this).scrollTop()、$(window).height()与$(document).height()关系。
fn = fn || function() {};
代码中使用了一句 fn = fn || function() {}; ,这是什么意思呢?
|| 符号意思是,如果左边的为假,则整个返回值为右边的表达式;如果左边为真,则返回值为左边的表达式。
所以如果fn为真,那么fn = fn;否则,给fn一个空函数。
|| 通常用来给定默认值。&& 通常用来避免某个对象undefined时,继续取他的值。
someObj && someObj.someFunc 意思是,如果 someObj 存在,整个表达式为someObj.someFunc。
2、判断滑轮上滚下滚
 
这种方法是通过判断滑轮上滑下滑,来判断滚动条上滚下滚。
这种方法有很大的使用局限性,当用鼠标拖动滚动条时,该方法就失效了。如下图所示,判断不出滚动条上下滚动(鼠标滚动监控没出现up/down状态标识,控制台没输出)。
 
这种方法还不能应用于手机上,在手机上滑动时根本获取不到上滑下滑的状态。如图所示(鼠标滚动监控没出现up/down状态标识):
 
所以,这种通过判断滑轮上滑下滑的方法是有很大的使用局限性的。
最后附上判断滑轮上滑下滑的JS代码:
 var scrollFunc = function(e) {
         e = e || window.event;
         //先判断浏览器IE,谷歌滑轮事件
         if (e.wheelDelta) {
             if (e.wheelDelta > 0) {
                 console.log("up");
             }
             if (e.wheelDelta < 0) {
                 console.log("down");
             }
             //Firefox滑轮事件   
         } else if (e.detail) {
             if (e.detail > 0) {
                 console.log("down");
             }
             if (e.detail < 0) {
                 console.log("up");
             }
         }
}
//给页面绑定滑轮滚动事件 
 if (document.addEventListener) {
     document.addEventListener('DOMMouseScroll', scrollFunc, false);
 }
 window.onmousewheel = document.onmousewheel = scrollFunc;3、判断滚动条上滚下滚(加强版)
 
据说第一种方法在苹果手机使用效果欠佳(通过滚动条上滑下滑显示隐藏导航条有跳动现象),于是就有了加强版出来。
判断滚动条上滚下滚(加强版) ,其实是在第一种方法的基础上,做了一些改进,思路是,它在滚动条持续下滑或上滑时,只执行一次,避免(第一种方法)时刻判断下滑上滑从而不断执行显示/隐藏导航条的代码。我们看上图的控制台输出,down和up前面是没有数字的,数字代表代码的执行次数。
JS代码如下:
   function scrollDirect(fn) {
       var beforeScrollTop = $(this).scrollTop();
       fn = fn || function() {};
       window.addEventListener("scroll", function(event) {
           event = event || window.event;
           var afterScrollTop = $(this).scrollTop();
           delta = afterScrollTop - beforeScrollTop;
           beforeScrollTop = afterScrollTop;
           var scrollTop = $(this).scrollTop();
           var scrollHeight = $(document).height();
           var windowHeight = $(this).height();
           if (afterScrollTop < 10 || afterScrollTop > $(document.body).height() - 10) {
               fn('up');
           } else {
               if (Math.abs(delta) < 10) {
                   return false;
               }
               fn(delta > 0 ? "down" : "up");
           }
       }, false);
   }
   var upflag = 1;
   var downflag = 1;
   //scroll滑动,上滑和下滑只执行一次!
   scrollDirect(function(direction) {
       if (direction == "down") {
           if (downflag) {
               console.log("down");
               downflag = 0;
               upflag = 1;
           }
       }
       if (direction == "up") {
           if (upflag) {
               console.log("up");
               downflag = 1;
               upflag = 0;
           }
       }
   });总结
本文通过亲测!详细介绍了JS判断滚动条上滚下滚的三种方法,明白这几种方法之间的区别,以及它们的使用局限。第一种方法代码少简单明了,推荐使用,不过据说在苹果手机使用效果欠佳(本人未经测试),第二种方法使用有很大的局限性,不建议使用,而第三种方法是第一种方法的加强版,使用效果可以在各种手机上表现良好,但代码略像繁琐。
 
 


