• jQuery插件stickup.js 源码解析初步


    这里只是一个初步的解析

    stickup.js是一个简单的jQuery插件,源代码只有100多行,它能让页面目标元素 “固定” 在浏览器窗口的顶部,即便页面在滚动,目标元素仍然能出现在设定的位置。

    介绍:http://www.bootcss.com/p/stickup/

    源码地址:https://github.com/LiranCohen/stickUp

    同时,还有一个改进版本可以参考:http://www.cnblogs.com/vans/p/3789416.html

    源码地址:https://github.com/VanMess/stickUp

      1 jQuery(function($) {
      2     
      3     $(document).ready(function(){
      4         var contentButton = [];
      5         var contentTop = [];
      6         var content = [];
      7         var lastScrollTop = 0;
      8         var scrollDir = '';
      9         var itemClass = '';
     10         var itemHover = '';
     11         var menuSize = null;
     12         var stickyHeight = 0;
     13         var stickyMarginB = 0;
     14         var currentMarginT = 0;
     15         var topMargin = 0;
     16 
     17 
     18         $(window).scroll(function(event){
     19                var st = $(this).scrollTop();
     20                if (st > lastScrollTop){
     21                    scrollDir = 'down';
     22                } else {
     23                   scrollDir = 'up';
     24                }
     25               lastScrollTop = st;
     26         });
     27 
     28         /***********************************************************/
     29         $.fn.stickUp = function( options ) {
     30             // adding a class to users div
     31             $(this).addClass('stuckMenu');
     32             //getting options
     33             var objn = 0;    //objn表示导航条对象有n个
     34             if(options != null) {
     35                 for(var o in options.parts) {    //option.parts指导航条对象
     36                     if (options.parts.hasOwnProperty(o)){
     37                         content[objn] = options.parts[objn];    //content对象是options.parts的深拷贝
     38                         objn++;
     39                     }
     40                 }
     41                   if(objn == 0) {
     42                       console.log('error:needs arguments');
     43                   }
     44 
     45                   itemClass = options.itemClass;
     46                   itemHover = options.itemHover;
     47 
     48                   itemTop = options.topLength;    //新添加
     49 
     50                   if(options.topMargin != null) {
     51                       if(options.topMargin == 'auto') {
     52                           topMargin = parseInt($('.stuckMenu').css('margin-top'));
     53                       } else {
     54                           //如果以px结尾的topMargin,如options.topMargin:10px,则topMargin=10    此处是否有bug,如 abcpx
     55                           if(isNaN(options.topMargin) && options.topMargin.search("px") > 0){
     56                               topMargin = parseInt(options.topMargin.replace("px",""));
     57                           //如果topMargin是数字,如options.topMargin:10,则topMargin=10                          
     58                           } else if(!isNaN(parseInt(options.topMargin))) {
     59                               topMargin = parseInt(options.topMargin);
     60                           } else {
     61                               //既不是数字,也不是以px结尾,也不是auto,那么就默认为0
     62                               console.log("incorrect argument, ignored.");
     63                               topMargin = 0;
     64                           }    
     65                       }
     66                   } else {
     67                       topMargin = 0;
     68                   }
     69                   menuSize = $('.'+itemClass).size();    //menuSize指jQuery选择器匹配的元素的数量
     70               }
     71             stickyHeight = parseInt($(this).height());
     72             stickyMarginB = parseInt($(this).css('margin-bottom'));
     73             currentMarginT = parseInt($(this).next().closest('div').css('margin-top'));
     74             vartop = parseInt($(this).offset().top);
     75 
     76             varleft = parseInt($(this).offset().left);    //新添加
     77             varParentWidth = parseInt($(this).parent().offset().width());    //新添加:计算菜单栏悬浮时的宽度
     78             varParentLeft = parseInt($(this).parent().offset().left);    //新添加:计算菜单栏悬浮时的距离在屏幕左边的宽度
     79 
     80             //$(this).find('*').removeClass(itemHover);
     81         }
     82 
     83         //document对象绑定滚动事件,通过监听滚轮位置来识别内容位置,给导航栏切换对应样式
     84         $(document).on('scroll', function() {
     85             //scrollTop()方法返回或设置匹配元素的滚动条的垂直位置。
     86             //如果该方法未设置参数,则返回以像素计的相对滚动条顶部的偏移。
     87             varscroll = parseInt($(document).scrollTop());    
     88 
     89             if(menuSize != null){
     90                 for(var i=0;i < menuSize;i++)
     91                 {
     92                     contentTop[i] = $('#'+content[i]+'').offset().top;    //当前内容位置的偏移(第一个元素匹配的偏移坐标)
     93                     function bottomView(i) {
     94                         contentView = $('#'+content[i]+'').height()*.4;    //当前内容区域高度的 0.4
     95                         testView = contentTop[i] - contentView;    //当前内容区域往上
     96                         //console.log(varscroll);
     97                         if(varscroll > testView){
     98                             $('.'+itemClass).removeClass(itemHover);
     99                             $('.'+itemClass+':eq('+i+')').addClass(itemHover);    //eq() jQuery遍历方法,下标从0开始
    100                         }
    101                         //只距离顶部50px,则默认为导航条的第0个对象 
    102                         else if(varscroll < 50){    
    103                             $('.'+itemClass).removeClass(itemHover);
    104                             $('.'+itemClass+':eq(0)').addClass(itemHover);
    105                         }
    106                     }
    107 
    108                     //滚轮往下走,而且偏移量大于当前内容位置往上50px,且小于往下50px时,
    109                     //即表示当前内容选中,为当前内容的在导航条上的项目添加active样式
    110                     if(scrollDir == 'down' && varscroll > contentTop[i]-50 && varscroll < contentTop[i]+50) {
    111                         $('.'+itemClass).removeClass(itemHover);
    112                         $('.'+itemClass+':eq('+i+')').addClass(itemHover);
    113                     }
    114                     //如果滚轮往上走,则调用上面的函数判断
    115                     if(scrollDir == 'up') {
    116                         bottomView(i);
    117                     }
    118                 }
    119             }
    120 
    121 
    122             /* 参考示例
    123             if(scrollDir == 'up') {
    124                 for(var i=1;i < menuSize;i++)
    125                 {
    126                     //滚轮往上走的时候默认100以内的宽度让上方的项目增加active样式
    127                     if(varscroll > $('#'+content[i-1]+'').offset().top && varscroll < $('#'+content[i]+'').offset().top-100){
    128                         $('.'+itemClass).removeClass(itemHover);
    129                         $('.'+itemClass+':eq('+(i-1)+')').addClass(itemHover);
    130                     }
    131                 }
    132             }*/
    133 
    134 
    135 
    136             //两个IF判断滚轮位置是否超过导航条距离屏幕上方高度,
    137             //如果超过了,就让导航条浮起来,相反就让导航条回到文档流中
    138             if(vartop < varscroll + topMargin){
    139                 $('.stuckMenu').addClass('isStuck');
    140                 $('.stuckMenu').next().closest('div').css({
    141                     'margin-top': stickyHeight + stickyMarginB + currentMarginT + 'px'
    142                 }, 10);
    143                 $('.stuckMenu').css("position","fixed");
    144                 $('.isStuck').css({
    145                     top: '0px'
    146                 }, 10, function(){
    147 
    148                 });
    149             };
    150 
    151             if(varscroll + topMargin < vartop){
    152                 $('.stuckMenu').removeClass('isStuck');
    153                 $('.stuckMenu').next().closest('div').css({
    154                     'margin-top': currentMarginT + 'px'
    155                 }, 10);
    156                 $('.stuckMenu').css("position","relative");
    157             };
    158 
    159         });
    160     });
    161 
    162 });
  • 相关阅读:
    Antelope 和Barracuda区别
    MySQL监控工具-orztop
    MySQL监控工具-orzdba
    CentOS7 下 Hadoop 单节点(伪分布式)部署
    MyBatis-获取 xxxMapper(源码)
    MyBatis-获取 SqlSession(源码)
    Java-获取 JDK 动态代理生成的 Class 文件
    MyBatis-SqlSessionFactory 的创建(源码)
    JAVA-Enum 枚举
    JAVA-Proxy 代理
  • 原文地址:https://www.cnblogs.com/shiddong/p/5683888.html
Copyright © 2020-2023  润新知