左右运动版轮播图案例(35)

 

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>轮播图</title>
    <link rel="stylesheet" href="css/reset.min.css">
    <link rel="stylesheet" href="css/banner.css">
</head>
<body>
<section class="container" id="container">
    <div class="wrapper">
        <!--<div class="slide"><img src="img/banner1.jpg" alt=""></div>
        <div class="slide"><img src="img/banner2.jpg" alt=""></div>
        <div class="slide"><img src="img/banner3.jpg" alt=""></div>
        <div class="slide"><img src="img/banner4.jpg" alt=""></div>-->
    </div>
    <ul class="focus">
        <!-- <li class="active"></li>
         <li></li>
         <li></li>
         <li></li>-->
    </ul>
    <a href="javascript:;" class="arrow arrowLeft"></a>
    <a href="javascript:;" class="arrow arrowRight"></a>
</section>

<!--<section class="container" id="container2">
    <div class="wrapper">
        &lt;!&ndash;<div class="slide"><img src="img/banner1.jpg" alt=""></div>
        <div class="slide">
            <img src="img/banner2.jpg" alt="">
        </div>
        <div class="slide"><img src="img/banner3.jpg" alt=""></div>
        <div class="slide"><img src="img/banner4.jpg" alt=""></div>&ndash;&gt;
    </div>
    <ul class="focus">
        &lt;!&ndash; <li class="active"></li>
         <li></li>
         <li></li>
         <li></li>&ndash;&gt;
    </ul>
    <a href="javascript:;" class="arrow arrowLeft"></a>
    <a href="javascript:;" class="arrow arrowRight"></a>
</section>-->

<script src="js/animate.js"></script>
<script src="js/banner-委托.js"></script>

</body>
</html>
.container {
    position: relative;
    margin: 20px auto;
    width: 1000px;
    height: 300px;
    overflow: hidden;
}

.container .wrapper {
    position: absolute;
    top: 0;
    left: 0;
    width: 4000px; /*根据JS中获取的数据动态控制宽度*/
    height: 100%;
}

.container .wrapper .slide {
    float: left;
    width: 1000px;
    height: 100%;
    overflow: hidden;
}

.container .wrapper .slide img {
    display: block;
    width: 100%;
    height: 100%;
}

.container .focus {
    position: absolute;
    z-index: 999;
    bottom: 10px;
    left: 50%;
    transform: translateX(-50%); /*基于CSS3中的TRANSFORM变形属性,在不固定的宽度的情况下实现水品居中 translateX:让当前元素在水平方向发生位移(此处-50%向左移动当前盒子的一半)*/

    padding: 4px;
    height: 12px;
    background: rgba(0, 0, 0, .5);
    border-radius: 10px; /*让其为盒子高度的一半,这样把长方型的盒子修改为椭圆状*/
    font-size: 0;
}

.container .focus li {
    display: inline-block;
    margin: 0 4px;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: #FFF;
    cursor: pointer;
}

.container .focus li.active {
    background: #DB192A;
}

.container .arrow {
    display: none;
    position: absolute;
    top: 50%;
    margin-top: -22.5px;
    width: 28px;
    height: 45px;
    background: url("../img/pre.png") no-repeat;
    opacity: 0.3;
}

.container .arrow:hover {
    opacity: 1;
}

.container .arrow.arrowLeft {
    left: 0;
    background-position: 0 0;
}

.container .arrow.arrowRight {
    right: 0;
    background-position: -50px 0;
}
let bannerRender = (function () {
    //->获取后续需要操作的元素对象或者元素集合
    let container = document.querySelector('#container'),
        wrapper = container.querySelector('.wrapper'),
        focus = container.querySelector('.focus'),
        arrowLeft = container.querySelector('.arrowLeft'),
        arrowRight = container.querySelector('.arrowRight'),
        slideList = null,
        focusList = null;

    //=>轮播图运动的基础参数
    let stepIndex = 0,//=>STEP-INDEX记录当前展示块的索引(步长)
        autoTimer = null,//=>AUTO-TIMER自动轮播的定时器
        interval = 3000;//=>INTERVAL间隔多长时间自动切换一次

    //=>AUTO-MOVE:控制轮播图的运动和切换
    /*
     * 索引为1,展示第二张,WRAPPER的LEFT -1000
     * 索引为2,展示第三张,WRAPPER的LEFT -2000
     * ...
     * WRAPPER的LEFT值其实就是当前要展示的图片索引对应的结果:-索引*1000
     */
    let autoMove = function autoMove() {
        stepIndex++;
        if (stepIndex >= slideList.length) {//=>stepIndex>(slideList.length-1)
            //=>说明再往后切换没有了(现在展示的是克隆的第一张),此时我们让WRAPPER立即回到真实第一张的位置(LEFT=0),然后STEP-INDEX=1(这样可以切换到第二张)
            utils.css(wrapper, 'left', 0);
            stepIndex = 1;
        }
        //->基于自主封装的ANIMATE实现切换动画
        animate(wrapper, {
            left: -stepIndex * 1000
        }, 200);//=>200是从当前切换到下一张的动画时间 INTERVAL间隔多久切换一次

        //->每一次运动完成需要让焦点跟着切换
        changeFocus();
    };

    //=>CHANGE-FOCUS:让焦点跟着轮播图的切换而切换
    //(运动到克隆这一张的时候,也需要让第一个LI有选中的样式)
    let changeFocus = function changeFocus() {
        //=>当轮播图运动到最后一张(克隆的第一张,我们需要让第一个LI[索引0]有选中的样式)(之所以使用TEMP-INDEX是因为STEP-INDEX对轮播图的切换有很大作用,不能轻易修改)
        let tempIndex = stepIndex;
        tempIndex === slideList.length - 1 ? tempIndex = 0 : null;
        [].forEach.call(focusList, (item, index) => {
            item.className = index === tempIndex ? 'active' : '';
        });
    };

    //=>QUERY-DATA:获取数据
    let queryData = function queryData() {
        return new Promise((resolve, reject) => {
            let xhr = new XMLHttpRequest;
            xhr.open('GET', 'json/banner.json');//=>第三个参数不写或者写TRUE都是异步编程
            xhr.onreadystatechange = () => {
                if (xhr.readyState === 4 && xhr.status === 200) {
                    let data = JSON.parse(xhr.responseText);
                    resolve(data);
                }
            };
            xhr.send(null);
        });
    };

    //=>BIND-HTML:数据绑定
    let bindHTML = function bindHTML(data) {
        let strSlide = ``,
            strFocus = ``;
        data.forEach((item, index) => {
            //->解构的时候如果当前返回的数据中没有IMG,我们可以让其等于默认图片
            let {img = 'img/banner1.jpg', desc = '珠峰培训'} = item;
            strSlide += `<div class="slide">
                <img src="${img}" alt="${desc}">
            </div>`;

            //->ES6模板字符串中${}存放的是JS表达式,但是需要表达式有返回值,因为我们要把这个返回值拼接到模板字符串中
            strFocus += `<li class="${index === 0 ? 'active' : ''}">
            </li>`;
        });

        //=>把第一张克隆一份放到最末尾
        // strSlide += `<div class="slide">
        //     <img src="${data[0].img}" alt="${data[0].desc}">
        // </div>`;

        wrapper.innerHTML = strSlide;
        focus.innerHTML = strFocus;

        //->获取所有的SLIDE和LI
        slideList = wrapper.querySelectorAll('.slide');
        focusList = focus.querySelectorAll('li');

        //->把现有的第一张克隆一份放到容器的末尾(由于querySelectorAll不存在DOM映射,新增加一个原有集合中还是之前的SLIDE,所以我们需要重新获取一遍)
        wrapper.appendChild(slideList[0].cloneNode(true));
        slideList = wrapper.querySelectorAll('.slide');

        //->根据SLIDE的个数动态计算WRAPPER的宽度
        utils.css(wrapper, 'width', slideList.length * 1000);
    };

    //=>HANDLE-CONTAINER:鼠标进入和离开控制自动的轮播的停止和开启
    let handleContainer = function handleContainer() {
        container.onmouseenter = function () {
            clearInterval(autoTimer);
            arrowLeft.style.display = arrowRight.style.display = 'block';
        };
        container.onmouseleave = function () {
            autoTimer = setInterval(autoMove, interval);
            arrowLeft.style.display = arrowRight.style.display = 'none';
        };
    };

    //=>HANDLE-FOCUS:点击焦点实现切换
    let handleFocus = function handleFocus() {
        [].forEach.call(focusList, (item, index) => {
            item.onclick = function () {
                stepIndex = index;//=>点击的是谁,就让STEP-INDEX运动到哪(STEP-INDEX和点击LI的索引一致即可)
                animate(wrapper, {
                    left: -stepIndex * 1000
                }, 200);
                changeFocus();
            };
        });
    };

    //=>HANDLE-ARROW:给两个按钮绑定点击事件
    let handleArrow = function handleArrow() {
        arrowRight.onclick = autoMove;//=>点击右边的按钮和自动轮播是一样的(执行AUTO-MOVE即可实现效果)

        arrowLeft.onclick = function () {
            stepIndex--;
            //=>如果索引减减小于零,说明当前已经是第一张,不能在向右运动了,此时我们让WRAPPER瞬间移动到最后一张(最后一张和第一张一模一样),在让其运动到倒数第二张即可
            if (stepIndex < 0) {
                utils.css(wrapper, 'left', -(slideList.length - 1) * 1000);
                stepIndex = slideList.length - 2;
            }
            animate(wrapper, {
                left: -stepIndex * 1000
            }, 200);
            changeFocus();
        };
    };

    return {
        init: function init() {
            let promise = queryData();
            promise.then(bindHTML).then(() => {
                //=>开启定时器驱动的自动轮播
                autoTimer = setInterval(autoMove, interval);
            }).then(() => {
                //=>左右按钮或者焦点切换
                handleContainer();
                handleFocus();
                handleArrow();
            });
        }
    }
})();
bannerRender.init();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值