原生js实现无缝轮播

原生js实现无缝轮播

  因为要做到无缝,所以就要把第一张图片和最后一张连接起来,在此处采用js克隆了第一张图片的节点,添加到最后,显示图片序号的小圆按钮也是使用js动态添加的。

  1. html部分
        <div class="banner" id="banner">
            <ul class="pic" id="pic">
                <li><a href="javascript:void(0)"><img src="images/1.jpg"></a></li>
                <li><a href="javascript:void(0)"><img src="images/2.png"></a></li>
                <li><a href="javascript:void(0)"><img src="images/3.png"></a></li>
                <li><a href="javascript:void(0)"><img src="images/4.png"></a></li>
                <li><a href="javascript:void(0)"><img src="images/5.jpg"></a></li>
                <li><a href="javascript:void(0)"><img src="images/6.png"></a></li>
                <li><a href="javascript:void(0)"><img src="images/7.png"></a></li>
            </ul>
            <ul class="dot" id="dot"></ul>
            <button class="left" id="leftBtn">&lt;</button>
            <button class="right" id="rightBtn">&gt;</button>
        </div>

     

  2. css部分
           * {
                padding: 0;
                margin: 0;
            }
            .banner {
                width: 1000px;
                height: 600px;
                margin: 0 auto;
                position: relative;
                overflow: hidden;
            }
            ul, li {
                list-style: none;
            }
            .pic {
                height: 600px;
                position: absolute;
                left: 0;
                top: 0;
            }
            .pic li {
                float: left;
            }
            .pic li img {
                width: 1000px;
                height: 600px;
            }
            .dot {
                width: 100%;
                text-align: center;
                font-size: 0;
                position: absolute;
                bottom: 40px;
                left: 0;
            }
            .dot li {
                display: inline-block;
                width: 10px;
                height: 10px;
                border-radius: 50%;
                background-color: #fff;
                margin: 0 5px;
                cursor: pointer;
            }
            .banner button {
                width: 30px;
                height: 50px;
                background-color: rgba(0, 0, 0, .5);
                border: 0 none;
                color: #fff;
                opacity: .5;
                position: absolute;
                top: 45%;
                cursor: pointer;
                font-size: 24px;
            }
            .left {
                left: 0;
            }
            .right {
                right: 0;
            }

     

  3. js部分
            js中有封装的一些方法,包括查看对象属性的兼容写法,动画函数(该方法实现了height,width,left,top,opacity等属性的动画效果),和通过事件冒泡找寻节点的函数;
           下方按钮的点击使用了事件委托实现,省去了为每个小圆点都设置点击事件。
            var leftBtn = document.getElementById("leftBtn");
            var rightBtn = document.getElementById("rightBtn");
            var banner = document.getElementById("banner");
            var pic = document.getElementById("pic");
            var dot = document.getElementById("dot");
            for (var i = 0; i < pic.children.length; i++) {
                var node = document.createElement("LI");
                node.index = i;
                dot.appendChild(node);
            }
            var copy = pic.children[0].cloneNode(true);
            pic.appendChild(copy);
            var width = parseInt(getStyle(pic.children[0], "width"));
            var len = pic.children.length;
            pic.style.width = width * len + "px";
            var index = 0;
            var t;
            function move() {
                if(index == len) {
                    pic.style.left = 0;
                    index = 1;
                }
                if (index == -1) {
                    pic.style.left = -(len - 1) * width + "px";
                    index = len - 2;
                }
                left = -width * index;
                changeDots(index);
                animate(pic, {left, left}, function() {
                    t = setTimeout(function () {
                        index++;
                        if (index == len) {
                            pic.style.left = 0;
                            index = 1;
                        }
                        move();
                    }, 2000);
                });
            }
            move();
            // 为按钮添加点击事件
            dot.onclick = function(e) {
                e = e || window.event;
                var target = e.target || e.srcElement;
                target = getTarget(target, "tagName", "LI", this);
                if (target) {
                    clearTimeout(t);
                    index = target.index;
                    changeDots(index);
                    move();
                }
            }
            // 左右按钮
            leftBtn.onclick = function() {
                clearTimeout(t);
                index--;
                move();
            }
            rightBtn.onclick = function() {
                clearTimeout(t);
                index++;
                move();
            }
            // 改变按钮颜色
            function changeDots(index) {
                if (index < 0) {
                    index = len;
                }
                if (index == len - 1) {
                    index = 0;
                }
                for (var i = 0; i < len - 1; i++) {
                    dot.children[i].style.backgroundColor = "#fff";
                }
                dot.children[index].style.backgroundColor = "red";
            }
            /**
             * 查看ele对象的type属性
             * @param {元素对象} ele 
             * @param {属性} type 
             */
            function getStyle(ele, type) {
                if (ele.currentStyle) {
                    return ele.currentStyle[type];
                } else {
                    return getComputedStyle(ele, null)[type];
                }
            }
            /**
             * 动画效果
             * @param {元素对象} el 
             * @param {结束条件} endObj 
             * @param {回调函数} cb 
             * @param {时间} time 
             */
            function animate(el, endObj, cb, time) {
                time = time || 200;
                var startObj = {};
                var _startObj = {};
                var speedObj = {};
                for (var i in endObj) {
                    startObj[i] = parseInt(getStyle(el, i));
                    _startObj[i] = startObj[i];
                    speedObj[i] = 16.7 * (endObj[i] - startObj[i]) / time;
                }
                var flag = false;
                clearInterval(el.t);
                el.t = setInterval(function() {
                    for (var j in endObj) {
                        startObj[j] += speedObj[j];
                        if (_startObj[j] < endObj[j] ? startObj[j] >= endObj[j] : startObj[j] <= endObj[j]) {
                            startObj[j] = endObj[j];
                            clearInterval(el.t);
                            flag = true;
                        }
                        if (j == "opacity") {
                            el.style[j] = startObj[j];
                        } else {
                            el.style[j] = startObj[j] + "px";
                        }
                    }
                    if (flag && cb) {
                        cb();
                    }
                }, 16.7);
            }
            /**
             * 找到attr属性为value的节点
             * @param {目标对象,鼠标点击对象} target 
             * @param {属性名} attr 
             * @param {属性值} value 
             * @param {结束条件} end 
             */
            function getTarget(target, attr, value, end) {
                while (target != end) { //如果鼠标点击的是end,则直接结束
                    if (target[attr] == value) { //如果点击的对象的attr属性值为value,则返回该对象
                        return target;
                    }
                    target = target.parentNode; //否则查找其父节点
                }
            }

     

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值