原生JS实现轮播

1.首先我们确定一下轮播图的思路。

1.我们用一个div充当容器
2.我们在这个div容器当中引入ul标签
3.我们将轮播的图片填充到ul标签下的li标签
4.通过设置css样式使得轮播图片在同行排列并且设置多余的图片隐藏
5.给轮播图添加各种控件并设置样式
6.写js代码使轮播图运动起来

2.让我们开始吧

 <div class="wrapper">
 //轮播图区域
        <ul id="sliderPage">
            <li><img src="cat1.jpg" alt=""></li>
            <li><img src="cat2.jpg" alt=""></li>
            <li><img src="cat3.jpg" alt=""></li>
            <li><img src="cat4.jpg" alt=""></li>
            <li><img src="cat1.jpg" alt=""></li>
        </ul>
        <div class="sliderIndex">
        //轮播的小圆点
            <i class="active"></i>
            <i></i>
            <i></i>
            <i></i>
        </div>
        //向左的控制按钮
        <div class="btn leftBtn" id="leftBtn">&lt</div>
        //向右的控制按钮
        <div class="btn rightBtn" id="rightBtn">&gt</div>
    </div>

然后我们设置css样式

 <style type="text/css">
        *{
            margin: 0;
            padding: 0;
            list-style: none;
        }
        .wrapper{
            position: relative;
            margin: 100px auto;
            width: 400px;
            height: 200px;
            border:1px solid black;
            overflow: hidden;
        }
        .wrapper ul {
            position: absolute;
            left:0px;
            top:0px;
            width: 2000px;
            height: 200px;
        }
        .wrapper ul li{
            float: left;
            width: 400px;
            height: 200px;
        }
        .wrapper ul li img{
            width: 400px;
            height: 200px;
        }
        .wrapper .sliderIndex{
            position: absolute;
            bottom: 10px;
            left: 50%;
            width: 80px;
            height: 20px;
            margin-left: -40px;
            text-align: center;
        }
        .wrapper .sliderIndex i{
            display: inline-block;
            width: 8px;
            height: 8px;
            border-radius: 50%;
            background-color: black;
            margin-right: 6px;
            cursor: pointer;
        }
        .wrapper .sliderIndex i.active{
            background: red;
            width: 12px;
            height: 12px;
        }
        .wrapper .btn{
            position: absolute;
            width:30px;
            height: 30px;
            background: black;
            opacity: 0.5;
            margin-top: -15px;
            top:50%;
            line-height: 30px;
            color: white;
            text-align: center;
            cursor: pointer;
        }
        .wrapper .btn.leftBtn{
            left: 20px;
        }
        .wrapper .btn.rightBtn{
            right: 20px;
        }
        .wrapper .btn:hover {
            opacity: 1;
        }
    </style>

这里几个主要的地方在于:
1.我们通过给li标签设置左浮动,让几张轮播图能够同行排列(类似胶片的效果)
2.给外面div容器设置overflow: hidden让多余的图片隐藏,因为我们轮播图每次只完整显示一张图片(切换过程不算)
3.然后给控件添加css样式,轮播图的小圆点我们用i标签实现,但是i标签是行内元素,对其设置宽高无效所以我们设置display: inline-block使其能够变成行内块级元素设置宽高,且不会换行。
4.其次我们对按钮设置样式
在这里插入图片描述

3.用js实现轮播

1.首先我们完成运动函数move.js

//获取元素当前的属性值
function getStyle (obj, attr) {
//兼容性处理
    if (obj.currentStyle) {
        return obj.currentStyle[attr];
    }else {
        return window.getComputedStyle(obj, false)[attr];
    }
}

function startMove (obj, data, func) {
    clearInterval(obj.timer);
    var iSpeed;
    var iCur;
    var name;
    startTimer = obj.timer = setInterval(function () {
    //变量bStop来控制着运动结束与否,因为有可能多个属性值都需要变化,我们需要所有属性值都运动到目标值才能结束我们的函数
        var bStop = true;
        //我们用for in遍历对象里的每一个属性,让他们都能够运动
        for (var attr in data) {
            if (attr === 'opacity') {
                name = attr;
                iCur = parseFloat(getStyle(obj, attr)) * 100;
            }else {
                iCur = parseInt(getStyle(obj, attr));
            }
            iSpeed = ( data[attr] - iCur) / 8;

            if (iSpeed > 0) {
                iSpeed = Math.ceil(iSpeed);
            }else {
                iSpeed = Math.floor(iSpeed);
            }

            if (attr === 'opacity') {
            //透明度(0~1)所以需要缩小一百倍
                obj.style.opacity = ( iCur + iSpeed ) / 100;
            }else {
                obj.style[attr] = iCur + iSpeed + 'px';
            }
            if ( Math.floor(Math.abs(data[attr] - iCur)) != 0 ) {
             //当存在任意属性值还未到该属性的目标值证明运动还没结束,将bStop设置成false继续运动
                bStop = false;
            }
        }
         //当运动全部结束,bStop变为true,清除定时器,执行回调函数
        if (bStop) {
            clearInterval(obj.timer);
            if (name === 'opacity') {
                obj.style.opacity = data[name] / 100;
            }
            func();
        }

    },30);
}

2.实现按钮控制轮播方向和自动轮播

<script>
//获取相应dom元素
        var sliderTimer = null;
        var sliderPage = document.getElementById("sliderPage");
        var leftBtn = document.getElementById("leftBtn");
        var rightBth = document.getElementById("rightBtn");
        var moveWidth = sliderPage.children[0].offsetWidth;
        var index = 0;
        var num = sliderPage.children.length - 1;
        var lock = true;
        var imgArr = document.getElementsByTagName('i');
//点击相应的索引跳到对应的轮播图
        for (var i = 0; i < imgArr.length; i++) {
        //这里使用立即执行函数是因为产生了闭包
            imgArr[i].onclick = (function(sliderIndex) {
                return function() {
                    clearInterval(sliderTimer);
                    index = sliderIndex;
                    changeIndex(index);
                    startMove(sliderPage, {
                        left: -moveWidth * sliderIndex
                    }, function() {
                        sliderTimer = window.setInterval(autoMove, 1500);
                        //这里是为了防止自动轮播到一半(此时lock = false)点击索引的圆点导致运动停止(进入不了if循环)
                        lock = true;
                    });
                }
            })(i);
        }



        leftBtn.onclick = function() {
        //从右向左轮播
            autoMove(-1);
        }
        rightBth.onclick = function() {
        //从左向右 也就是默认的轮播方向
            autoMove(1);
        }

        function autoMove(target) {
        //lock是为了防止在一次运动未完成的情况下多次点击按钮导致index超出,根本无法进行判断且导致left的属性值也超出范围使得函数无法正常执行
            if (lock) {
            //进入函数关闭锁
                lock = false;
                //为了点击按钮和默认轮播不冲突,每次运动都先清除定时器在后面再启动
                clearInterval(sliderTimer);
                //判断当target === 1或者undefined(即默认)证明是从左往右轮播
                if (target === 1 || !target) {
                    index++;
                    //并执行move.js里的startmove函数开始运动
                    startMove(sliderPage, {
                        left: sliderPage.offsetLeft - moveWidth
                    }, function() {
                    //这是index是图片的索引,当index===4证明已经从第一张图片重新开始轮播,并且将索引归0
                        if (index === 4) {
                            sliderPage.style.left = "0px";
                            index = 0;
                        }
                        sliderTimer = window.setInterval(autoMove, 1500);
                        lock = true;
                        changeIndex(index);
                    });
                } else if (target == -1) {
                //sliderPage.offsetLeft === 0证明此时轮播图在第一张
                    if (sliderPage.offsetLeft === 0) {
                    //这个时候点击左按键就应该跳转到最后一张轮播图
                        sliderPage.style.left = -moveWidth * num + 'px';
                        //index也变成最后轮播图的索引
                      index = num;
                    }
                    index--;
                    changeIndex(index);
                    startMove(sliderPage, {
                        left: sliderPage.offsetLeft + moveWidth
                    }, function() {
                        sliderTimer = window.setInterval(autoMove, 1500);
                        //函数结束,打开锁使得下次函数能够执行
                        lock = true;
                    });
                }
            }
        }
//每次图片轮播对应索引的小圆点添加active样式
        function changeIndex(index) {
            for (var i = 0; i < imgArr.length; i++) {
                imgArr[i].className = '';
            }
            imgArr[index].className = 'active';
        }
        sliderTimer = window.setInterval(autoMove, 1500)
    </script>

OK,大功告成

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值