微信号:FrontDev

介绍:分享 Web 前端相关的技术文章、工具资源、精选课程、热点资讯

实现小小的fullpage

2016-07-29 20:11 伯乐专栏\/小强

(点击上方公众号,可快速关注)

作者:伯乐在线专栏作者 - 前端-小强

链接:http://web.jobbole.com/87161/


需求背景


今天运营给了一个需求,要做个引导页,也就是全屏滚动。考虑到只有3张图,就自己码个吧!说干就干。


思路


  1. 设置一个外层container, 用户的可见区域,也就是全屏

  2. container内有3个层次,每个层次大小都跟container一样大小

  3. 每次滚动时候通过css的transform属性进行偏移,并结合transition过渡一下效果


*{

    margin: 0;

    padding: 0;

}

.container{

    position: fixed;

    top: 0;

    right: 0;

    bottom: 0;

    left: 0;

    z-index: 99999;

    overflow: hidden;

}

.scrollContainer{

    display: none;

    transition: all ease 1s;

}

.slide1{

    background-color: rgb(27, 188, 155);

}

.slide2{

    background-color: rgb(255, 153, 0);

}

.slide3{

    background-color: rgb(123, 170, 190);

}


<div class="container">

    <div class="scrollContainer">

        <div class="slide slide1">

        </div>

        <div class="slide slide2">

        </div>

        <div class="slide slide3">

        </div>

    </div>

</div>


scrollContainer是用来滚动内容的,所以在页面进入的时候要获取用户区域


var $container = $('.container');

var $scroll = $container.find('.scrollContainer');

var height = $container.height();

var len = 3;

var current = 1;

$container.find('.slide').css('height', height + 'px');

$scroll.show();


逻辑部分


为了防止滚动多次滚动,需要通过一个变量来控制是否滚动,这里的动画是1s执行完,使用setTimeout延迟1s后解锁,这样大体逻辑差不多


// page控制器

var len = 3;

var current = 1;

var page = {

    isScrolling: false,

    next: function() {

        if((current + 1) <= len) {

            current += 1;

            page.move(current);

        }

    },

    pre: function() {

        if(current -1 > 0) {

            current -= 1;

            page.move(current);

        }

    },

    move: function(index) {

        page.isScrolling = true;

        var di = -(index-1)*height + 'px';

        page.start = +new Date();

        $scroll.css('transform', 'translateY('+di+')');

        setTimeout(function(){

            page.isScrolling = false;

        }, 1010);

    }

};

// 滚动事件绑定

function bindMouseWheel (page) {

    var  type = 'mousewheel';

    var  deltaY = 0;

 

    function mouseWheelHandle (event) {

        if (page.isScrolling) {// 加锁部分

            return false;

        }

        var e = event.originalEvent || event;

 

        deltaY = e.deltaY;

        if (deltaY > 0) {

            page.next();

        } else if (deltaY < 0) {

            page.pre();

        }

    }

    $(document).on('mousewheel', mouseWheelHandle);

}


差不多了,大体已经完成,在浏览器中运行也几乎完美!但是我们是一家千牛应用,在运行,看似不错,但是鼠标快速移动就会出现闪屏、多滚动问题。


解决问题


出现这个问题,第一反应是代码写错了,没有兼容浏览器,但是一想千牛就是chrome内核,不需要写兼容代码啊!


方案1


不采用css动画,采用jquery动画。改变top值。

也尝试了这个方案,选择800毫秒效果相对最佳。


方案2


继续思考一开始的思路为啥出现问题。经过老大提醒,并结合千牛之前出现的css动画问题,感觉是动画结束和js控制没有达到一致。为了验证这个假设,去除setTimeout延迟,添加webkitTransitionEnd事件,并打印出每次滚动时间。


// page控制更改

move: function(index) {

    page.isScrolling = true;

    var di = -(index-1)*height + 'px';

    page.start = +new Date();

    $scroll.css('transform', 'translateY('+di+')');

},

// 添加了滚动结束控制

moveEnd: function() {

    page.end = +new Date();

    console.log('end', (page.end - page.start)/1000);

    page.isScrolling = false;

}

// 给添加滚动结束事件

$scroll.on('webkitTransitionEnd', page.moveEnd);


最终结果了滚动出现的问题,再查看每次滚动时间


end 1.022

end 1.055

end 2.344

end 2.273


在chrome里面查看滚动时间


end 0.999

end 0.994

end 1.006

end 1.023

end 0.991

end 0.997

end 1.005

end 1.046


结论


从结果来看在chrome里面css动画几乎没有延迟的跟设定1s过渡时间基本吻合,但是在里面能够看出css动画会受其他条件影响,比如上面所遇到的鼠标滚动过快等因素。


所以在css动画这方面就应该用css动画事件来控制。除了过渡有且只有webkitTransitionEnd事件,动画开始webkitAnimationStart,动画结束事件webkitAnimationEnd,动画重复运动事件 webkitAnimationIteration。后面再玩玩


专栏作者简介 ( 点击 → 加入专栏作者 


前端-小强:前端-小强,前端工程师,现就职于杭州光云科技,前端新人,对IT行业的花边新闻也感兴趣。http://xiaoqiang730730.github.io博客内容包括:解决日常问题的小技巧、对一些问题的思考、以及对某些事或者某些活动的思考。


【今日微信公号推荐↓】

更多推荐请看值得关注的技术和设计公众号


其中推荐了包括技术设计极客 和 IT相亲相关的热门公众号。技术涵盖:Python、Web前端、Java、安卓、iOS、PHP、C/C++、.NET、Linux、数据库、运维、大数据、算法、IT职场等。点击《值得关注的技术和设计公众号》,发现精彩!


 
前端大全 更多文章 18 行 JS 代码编一个倒时器 怎么写好组件 不容错过的 10 篇前端技术热文 Chrome 中的这个彩蛋,你知道吗? JS 统治的世界,烤面包机将能运行 JS 了
猜您喜欢 百度地图API自定义地图 世道变了 – 你愿意成为微软认证Linux工程师吗? 阿里月饼事件中的一个有趣现象 为什么我们很少做专家评估了? 敏捷破冰之旅(七)