前端札记让前端飞

用Vue.js写一个 自适应_等比缩放_无缝切换轮播

2018-12-15  本文已影响4人  kerush
前端入坑纪 51

周六就是分享日,来个上次vue.js轮播的小改款!

好,详解如下!

OK,first things first! github项目地址

还是很多喵
HTML 结构
    <div class="mainWrp" id="app">
        <div class="carousel">
            <ul class="imgsWrp clear" ref='imgsWrp' :style="'width:'+ lens * 100 + '%'">
                <li v-for="item in imgsArray" :style="'width:'+ 100 / lens + '%'" ref='imgs'>
                    <div class="imgsInner" :style="'background-image:url('+item+')'"></div>
                </li>
            </ul>
            <p><span ref='spanWrp'>1</span>/{{lens-1}}</p>
        </div>
    </div>

html结构中,相比之前,这次把样式都写到了对应的元素上。vue内置的ref="XX"属性,可以让我们在js中用this.$refs.XX直接获取(一个是ref,一个是refs哦)。

CSS 结构
        body,
        p,
        ul {
            margin: 0;
            padding: 0;
        }
        
        li {
            list-style: none
        }
        
        .mainWrp {
            width: 100%;
            max-width: 640px;
            overflow: hidden;
            margin: 0 auto
        }
        
        .clear::after {
            content: "";
            display: block;
            clear: both
        }
        
        .carousel {
            position: relative;
        }
        
        .carousel p {
            position: absolute;
            bottom: 0;
            right: 0;
            padding: 1px 5px;
            text-align: center;
            font-size: 12px;
            color: #333;
            background-color: rgba(255, 255, 255, .6)
        }
        
        .carousel span {
            color: #666
        }
        
        .imgsWrp {
            display:flex;
            flex-flow:row nowrap;                        
        }
        
        .imgsWrp li {
            flex:1 1 auto;
        }
        
        .imgsInner {
            width: 0;
            height: 0;
            padding:30% 50%;
            background-repeat:no-repeat;
            background-size:cover;
            background-position:center center
        }

这次轮播li里不是直接套图片img了,使用了我之前《自适应缩放图文列表》同样的原理,所有的图片都是设置div.imgsInner的背景。然后,用padding撑开div.imgsInner。ul里的li,使用的flex布局就不多赘述了,相关的文章资料好大一坨呢!

JavaScript 结构
        var vm = new Vue({
            el: "#app",
            data: {
                imgsArray: [],
                lens:0              
            },
            beforeCreate:function(){
                axios.get('imgslist.json')
                            .then(function(res) {   
                                var imgs = res.data.imgslist 
                                // 对获取的图片数组,复制第一张然后添加到它的最后面。[图1,图2,图3,......,图1]                            
                                imgs.push(imgs[0])
                                var lens =  vm.lens = imgs.length
                                vm.imgsArray=imgs
                                vm.lunbo(lens)                                                                                                                      
                            })                          
            },
            methods:{
                lunbo:function(lens){                        
                        var markSpan = this.$refs.spanWrp,
                        imgsWrp = this.$refs.imgsWrp,
                        timer = null;                        
                        i=0;

                        // 轮播每三秒要变动不同的图片
                        setInterval(function() {                            
                            i < lens - 1 ? i++ : i = 0;         
                        // 轮播的变动效果,之前是在css里,这次放到了js里,是为了后面有效的清空它                   
                            imgsWrp.style.transition="transform 700ms cubic-bezier(0.215, 0.610, 0.355, 1)"
                            imgsWrp.style.transform = "translateX(-" + 100 / lens * i + "%)";
                            markSpan.textContent = i + 1

                           // 当轮播到最后一张时,要做的处理
                            if(i+1==lens){
                                clearTimeout(timer)
                                // 将显示的数变成显示1(其实这里轮播就是播到最后一张,障眼法)
                                markSpan.textContent = 1
                               // 设置个1秒后的定时器,将动效的css清除,i置为0,然后imgsWrp的transform也变到0,也就是最开始的位置
                                timer = setTimeout(() => {
                                    imgsWrp.style.transition="none";
                                    i = 0;
                                    imgsWrp.style.transform = "translateX(0)";
                                }, 1000);                                
                            }
                        }, 3000)                   
                }
            },
            
        })

这里简述下,无缝切换的思路:因为最后一张和第一张是一样的,所以过渡效果到最后一张时,其实显示的是第一张的图片。也就是在这个时候,悄悄把下一次的切换从第二张图开始过渡。
补充说明下最关键的那个一秒的定时器:
1.为什么是1秒呢?因为动效的过渡时间为700ms,所以只要大于它,小于3秒就可以。

  1. imgsWrp.style.transition="none";的原因是要让做 imgsWrp.style.transform = "translateX(0)";操作的时候,不要产生过渡的效果。不然就被人看穿了。

好了,到此,本文告一段落!感谢您的阅读!祝你身体健康,阖家幸福!

打开支付宝首页搜 625097528 领红包,领到大红包的小伙伴赶紧使用哦!
支持你我,扫一扫红包
上一篇 下一篇

猜你喜欢

热点阅读