Stick up 实现原理

先上效果图:划过之后粘在页面之上,之后又取下来的感觉

Stick up 实现原理_第1张图片
Stick Up.gif

核心思路:

  • 1.你看到的粘在上面的nav的确是本体,不过已经被position:fixed,所以才有这种固定的效果;
  • 2.当本体fixed之后,因为脱离文档流,下面的元素势必会上来,这里会事先clone一个nav,insertBefore到本体的位置,然后让他opacity:0,再hide;
  • 3.当滑动到某个nav的位置的时候,本体display:fixed,clone体show()出来,撑住场面,不让页面散掉,当滑动小于某个距离的时候,clone体继续hide(),本地不再fixed,就是这么一个思路;

下面看看具体代码的实现过程吧:场景设定是 nav 来Stick up

Step0:我用的这个结构

    
aside1
main1
aside2
main2
aside3
main3

Step1:一些后面需要用到的变量

var $nav = $('.nav'),
        navH = $nav.height(),
        navW = $nav.width(),
        offsetLeft = $nav.offset().left,
        offsetTop = $nav.offset().top;
    var $cloneNav = $nav.clone().css('opacity',0).insertBefore($nav).hide();
    //这里的 $cloneNav 是这样一路下来的 

Step2:如何判断是否该元素是否到了该position:fixed?

$(window).on('scroll',function(){
        var scrollTop = $(this).scrollTop();
        if(scrollTop>= offsetTop){
            if(!isFixed()){
                setFixed();
            }
        }else{
            if(isFixed()){
                unsetFixed();
            }
        }
    });

这里先把思路理出来,当页面滚动的时候,“页面滚动的距离”是否大于“自己在页面的偏移的距离”,
大于就证明到了,就开始判断是否已经fixed,没有就setFixed,假如小于这个距离,就判断是否fixed,如果fixed就解除fixed;注意这里并没有把浏览器高度拉进来,是因为我是让他固定在浏览器上方;这一点和以后要说的懒加载又有点不一样,先挖个坑在这里;

Step3:如何setFixed呢?又是如何unsetFixed呢?

    function setFixed(){
        $nav.attr('position-fixed',true)
                .css({
                    position:'fixed',
                    top:0,
                    left:offsetLeft,
                    'z-index':7,
                    width:navW,
                    height:navH,
                    margin:0
                });
        $cloneNav.show();
    }
    function unsetFixed(){
        $nav.removeAttr('position-fixed').removeAttr('style');
        $cloneNav.hide();
    }

用到了jQuery的attr(),设置一个自定义标签,让经过set之后的元素有一个标记,然后用.css()来操纵本体,最后让clone体show出来,撑住场面,让页面不至于散架;
后面的解除fixed,就是把自己的自定义标签去除掉,并且把style(这里通过js操纵的样式都加在行内去了,所以用style来干涉),最后让clone体功成身退的hide掉

Step4:那么最终的问题,工具全部齐活了,最后的判断条件怎么写呢?

    function isFixed(){
        return !!$nav.attr('position-fixed');
    }

这里用的就是我设置的自定义标签,省去了一些功夫,直接判断是否存在这个标签,用了!!两次转换,因为已经fixed的话,返回的就是true,但是假如根本没有fixed,这个自定义标签就不会存在,就会使undifined,所以两次转换之后变成false,达到效果;

具体细节和可以上github查看

你可能感兴趣的:(Stick up 实现原理)