小小幻灯片

上一篇说了瀑布流,今天说一下小小幻灯片的故事。

幻灯片学名又叫 轮播。应当算是一种最经常运用的页面展现信息。之前因为ie6/7的拖累,致使我们只能运用,很陈旧的体式格局去兼容。(我最爱的css3啊~~~)。不过本年真的是前端的幸运年,种种 polyfill 和 shim,而且如今各大公司已对ie6/7不予理睬,直接给他一个提示页面(老子让你用ie6/7)。而且IE的爸爸,ms已表态了,我当初是怎样生下你来的,太tm丑了,因为开放二胎,ms已孵化了edge(原名斯巴达),如今基础上是前端的黄金时代了。这里我重要引见一种比较有用的轮播结果。

简朴轮播

轮播,在各大网站都是运用,比方在淘宝首页(兼容性比较好), 网易云音乐首页等等。 能够说,写轮播应当算是前端的一个必修课程吧。 我这里就挑一个最简朴的完成。

这里完成轮播的手艺,重要依靠与css3,js只是作为一个切换class名的作用(只要不写js都简朴)。

轮播道理

这里先说一下基础道理吧, 就是将图片 向左或向右移,然后接着显现下一张,或许上一张。

特么,逗我呢。你不说我也晓得哎喂。

咳咳~
我们来看一下,html部份吧。

<div class="sliderCon">
        <ul>
            <li class="current"><img src="http://www.w2bc.com/demo/201510/2015-10-20-html5-css3-focus-change/img/1.jpg" alt=""></li>
            <li><img src="http://www.w2bc.com/demo/201510/2015-10-20-html5-css3-focus-change/img/2.jpg" alt=""></li>
            <li><img src="http://www.w2bc.com/demo/201510/2015-10-20-html5-css3-focus-change/img/3.jpg" alt=""></li>
            <li><img src="http://www.w2bc.com/demo/201510/2015-10-20-html5-css3-focus-change/img/4.jpg" alt=""></li>
            <li><img src="http://www.w2bc.com/demo/201510/2015-10-20-html5-css3-focus-change/img/5.jpg" alt=""></li>
        </ul>
    </div>

这里就是经由过程ul包裹多个li完成的轮播。(这里须要谢谢一下爱编程供应的图片)

接着重头戏就是css3。
看~

.sliderCon {
    width: 100%;
    max-width: 100%;
    height: 100%;
    position: relative;
    text-align: center;
    ul {
        display: inline-block;
        position: relative;
        width: 450px;
        padding: 0;
        perspective: 1400px;
        li {
            width: 450px;
            height: 290px;
            position: absolute;
            list-style: none;
            top: 0;
            left: 0;
            opacity: 0;
            pointer-events: none;
            z-index: 1000;
            text-align: center;
            &.navOutNext {
                animation: rotate3DSlideOutLeft 0.3s forwards;
            }
            &.navInNext {
                animation: rotate3DSlideInRight 0.3s 0.1s forwards;
            }
            &.navOutPre{
                 animation: rotate3DSlideOutLeft 0.3s forwards;
            }
            &.navInPre{
                 animation: rotate3DSlideInRight 0.3s forwards;
            }
            &.current {  
                opacity: 1;
                pointer-events: auto;
                z-index: 1000;
            }
        }
    }
}

我这里只贴出重要部份的。 实在,贴出来基础没用,须要连系js来看。

js道理剖析

好吧,我继承贴哈。

js部份:

var slider = (function() {
    var order = 0,
        lis = $('.sliderCon li');
    var toggle = (function() { //经由过程flag来举行切换
        var current,
            next,
            isAnimated = false, //标识是不是正在实行动画
            mark = 0, //用来示意多个动画是不是都完毕
            len = lis.length - 1; //取得总的图片框
        var changeState = function() {
            mark++;
            if (mark === 2) {
                isAnimated = false;
                mark = 0;
            }
        }
        var nextExe = (function() {
            var setCurrentAnimate = function() {
                this.removeEventListener(transitionName, setCurrentAnimate);
                this.classList.remove("current");
                this.classList.remove("navOutNext");
                changeState(); //检测是不是动画都实行完全
            }
            var setNextAnimate = function() {
                this.removeEventListener(transitionName, setNextAnimate);
                this.classList.add("current");
                this.classList.remove('navInNext');
                changeState();
            }
            return function() {
                var current = lis[order];
                order = order + 1 > len ? 0 : order + 1;
                var next = lis[order]; //猎取下一个元素
                if (!transitionName) {
                    alert("你浏览器怎样这么渣滓,赶忙换一个吧");
                } else {
                    current.addEventListener(transitionName, setCurrentAnimate);
                    next.addEventListener(transitionName, setNextAnimate);
                }
                current.classList.add('navOutNext'); //最先实行动画
                next.classList.add('navInNext');
            }
        })();
        var preExe = (function(){
            var setCurrentAnimate = function() {
                this.removeEventListener(transitionName, setCurrentAnimate);
                this.classList.remove("current");
                this.classList.remove("navOutPre");
                changeState(); //检测是不是动画都实行完全
            }
            var setPreAnimate = function(){
                this.removeEventListener(transitionName, setPreAnimate);
                this.classList.add("current");
                this.classList.remove("navInPre");
                changeState(); //检测是不是动画都实行完全
            }
            return function(){
                var current = lis[order];
                order = order-1<0 ? len: order-1;
                 var pre = lis[order];  //取得下一个切换的元素
                if (!transitionName) {
                    alert("你浏览器怎样这么渣滓,赶忙换一个吧");
                } else {
                    current.addEventListener(transitionName, setCurrentAnimate);
                    pre.addEventListener(transitionName, setPreAnimate);
                }
                current.classList.add('navOutPre'); //最先实行动画
                pre.classList.add('navInPre');
            }
        })();
        return function(flag) { //进口函数
            if (isAnimated) return; //假如正在实行动画则退出
            isAnimated = true; //标识正在实行动画
            if (flag === "next") {
                nextExe();
            }else if(flag==="pre"){
                preExe();
            }
        }
    })();
    setInterval(function() {
        toggle("pre");
    }, 1000);
})();

因为我过分的运用了闭包和高阶函数,所以看起来会有点累哈。不急,一样,一个顺序我们先找进口函数。
能够看出。进口函数就是toggle(就是运用return 的那部份);

 return function(flag) { //进口函数
            if (isAnimated) return; //假如正在实行动画则退出
            isAnimated = true; //标识正在实行动画
            if (flag === "next") {
                nextExe();
            }else if(flag==="pre"){
                preExe();
            }
        }

isAnimated只是个标识符,用来示意是不是正在实行动画。经由过程传入的flag来示意向前切换照样向后切换。假如向后接环则实行nextExe函数。好,我们来看一下nextExe函数。

切换动画函数

var nextExe = (function() {
            var setCurrentAnimate = function() {
                this.removeEventListener(transitionName, setCurrentAnimate);
                this.classList.remove("current");
                this.classList.remove("navOutNext");
                changeState(); //检测是不是动画都实行完全
            }
            var setNextAnimate = function() {
                this.removeEventListener(transitionName, setNextAnimate);
                this.classList.add("current");
                this.classList.remove('navInNext');
                changeState();
            }
            return function() {
                var current = lis[order];
                order = order + 1 > len ? 0 : order + 1;
                var next = lis[order]; //猎取下一个元素
                if (!transitionName) {
                    alert("你浏览器怎样这么渣滓,赶忙换一个吧");
                } else {
                    current.addEventListener(transitionName, setCurrentAnimate);
                    next.addEventListener(transitionName, setNextAnimate);
                }
                current.classList.add('navOutNext'); //最先实行动画
                next.classList.add('navInNext');
            }
        })();

对不起,吓到人人了,我这里又写了一个闭包。。。 固然,重要进口函数照样在return 背面。
order用来标识当前的元素的序号。 须要注重的是增加动画监听的那一部份。我这里运用了一个tricks(from moderniz),我贴出来吧。

动画支撑检测

var transitionName = (function() {

    var t;

    var el = document.createElement('fakeelement');

    //实在运用animated完全能够庖代transition
    var transitions = {
        //这里是aniamted事宜
        'WebkitAnimation': 'webkitAnimationEnd',
        'OAnimation': 'oAnimationEnd',
        'msAnimation': 'MSAnimationEnd',
        'animation': 'animationend'
            //下面是transition事宜
            // 'transition':'transitionend',

        // 'OTransition':'oTransitionEnd',

        // 'MozTransition':'transitionend',

        // 'WebkitTransition':'webkitTransitionEnd',

        // 'MsTransition':'msTransitionEnd'

    }


    for (t in transitions) {

        if (el.style[t] !== undefined) {

            return transitions[t];

        }

    }

})();

实在这个IIFE重要的功用就是检测,你的浏览器究竟支撑哪个动画监听函数。 好,pass.
我们回到适才的主函数nextExe. 接着,我们给current和next增加监听,监听函数先放着。 接着我们给current和next增加动画(就是增加class). 就这样。然后他会触发监听函数。 这里就不过量引见了, 唯一须要说起的就是,须要在背面临监听举行解绑,防止反复绑定。

空话说完了。 直接看个实例吧。

slider实例
这应当算是最原始的轮播。 接着我们能够在上面加上一些我们想要的功用。这里我加上了一些比较经常运用的,比方,轮播标识符,摆布翻页。

因为比较简朴,我这里直接把实例贴出来。实在重要的干货就是最原始的轮播,其他的都是花花草草。

update slider

好了,大部份内容我也差不多引见完了。

说说轮播

上面基础上把简朴轮播的道理引见一遍,虽然说低版本的SB IE可能会不支撑。 但这个重要取决于你产物leader的范例,假如他要求是ie9+那末你运用这个应当题目不大,就是须要处置惩罚一下动画完毕事宜的支撑。假如甚者须要将ie8斟酌进来,那末,这个应当运用css的基础属性,而不能运用css3,或许直接运用js举行转变。照样那句话,站在你的角度去造一个unique轮子,就是最好的进修。

    原文作者:villainhr
    原文地址: https://segmentfault.com/a/1190000004395961
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞