Bootstrap

网站轮播图的实现-平移版

/*关于轮播图,相信大家都不陌生,各大网站上都有它的身影。
*那么我们如何实现这样一个东西呢?
*希望这篇博文能帮到你
*/

轮播图效果

/*上图就是我们今天需要实现的效果
先来确认一下我们的需求:
需求1:鼠标移入轮播图,显示上一页,下一页的箭头,鼠标移出消失
需求2:点击上一页,下一页实现图片切换,导航栏的数字效果跟着变化
需求3:点击导航页码,也可以实现图片切换
需求4:让他实现自动轮播,鼠标移入轮播图取消自动轮播
*/

/*首先先分析一下我们的页面构成,我们用一个div把可视区域、页码导航部分、上一页下一页包裹起来
可视区域包裹着一个ul标签,里面每一个li标签装有我们需要轮播的图片
设定ul的宽度等于li标签数量乘以图片的真实宽度(offsetWidth),让我们的图片呈一列显示,
无论用浮动还是定位的方式都可以,本例子用定位的方式,为什么叻?因为我们div还装有别的一些东西,
也需要用到定位,这样比较方便一点...代码后面呈现,我们现在开始从需求1开始分析
*/
需求1
这个需求实现比较简单,我们只需要给装有这些元素的大盒子加上一个onmouseover事件和onmouseout事件
让上一页下一页部分显示或者隐藏即可 用到display属性。

需求2
给我们的上一页下一页添加点击事件,onclick
页面默认显示第一张,所以我们可以设置一个变量index来记录我们当前轮播的是哪张图片。
每点击一次下一页index++,再调用我封装好的animation方法实现平移效果切换。(每点击一次,ul向左移动...实现图片切换)
紧接着,如果页码下标与index一致,说明是当前页面,需要改变样式
ok,这样一来,我们基本需求就实现了,那么现在问题又来了,当index达到第5张的时候,此时index=4,
我再点一次会发生什么情况?会发现ul移到了没有图片的地方,页码导航也随之没有了样式

这种情况,我们如何解决呢?为了更好的实现我们的效果,其实我们可以加多一行li代码存储第1张的图片,
当我们点击的时候,index=5,虽然我们程序员知道这是第六张,但在用户眼里,这就是第一张图片,
我们做一个特殊处理,将第一页的页码的样式修改。
当我们在第六张点击的时候,此时我们可以修改ul的位置,再将index设置为0,让它继续进行下一页的操作。
这样我们就可以神不知鬼不觉的实现我们的需求啦。
上一页也是同样的原理。

需求3
我们给每一个页码导航一个属性,让它代表它是对应的哪一张图片,
当我们点击页码的时候,将这个属性取出来,赋值给我们的全局变量index,
这样一来,我们就可以轻松的实现我们动画平移的效果,
再使用排他思想,除了点击的这个以外,样式清空,只给我们这个点击的赋予样式。

需求4
这个就比较简单了,设置一个定时器,每隔一秒钟触发一次下一页的函数体即可,
给大盒子的鼠标移入事件加入清除计时器的效果,移出的时候重新开启计时器效果,
PS:记得保存计时器id,用于清除

接下来看下我们完整的代码吧,希望这篇博文对你有帮助。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <style type="text/css">
        * {
            padding: 0;
            margin: 0;
            list-style: none;
            border: 0;
        }

        .all {
            width: 500px;
            height: 200px;
            padding: 7px;
            border: 1px solid #ccc;
            margin: 100px auto;
            position: relative;
        }

        .screen {
            width: 500px;
            height: 200px;
            overflow: hidden;
            position: relative;
        }

        .screen li {
            width: 500px;
            height: 200px;
            overflow: hidden;
            float: left;
        }

        .screen ul {
            position: absolute;
            left: 0;
            top: 0px;
            width: 3000px;
        }

        .all ol {
            position: absolute;
            right: 10px;
            bottom: 10px;
            line-height: 20px;
            text-align: center;
        }

        .all ol li {
            float: left;
            width: 20px;
            height: 20px;
            background: #fff;
            border: 1px solid #ccc;
            margin-left: 10px;
            cursor: pointer;
        }

        .all ol li.current {
            background: yellow;
        }

        #arr {
            display: none;
        }

        #arr span {
            width: 40px;
            height: 40px;
            position: absolute;
            left: 5px;
            top: 50%;
            margin-top: -20px;
            background: #000;
            cursor: pointer;
            line-height: 40px;
            text-align: center;
            font-weight: bold;
            font-family: '黑体';
            font-size: 30px;
            color: #fff;
            opacity: 0.3;
            border: 1px solid #fff;
        }

        #arr #right {
            right: 5px;
            left: auto;
        }
    </style>
</head>
<body>
<div class="all" id='box'>
    <div class="screen">
        <ul>
            <li><img src="images/01.jpg" width="500" height="200"/></li>
            <li><img src="images/02.jpg" width="500" height="200"/></li>
            <li><img src="images/03.jpg" width="500" height="200"/></li>
            <li><img src="images/04.jpg" width="500" height="200"/></li>
            <li><img src="images/05.jpg" width="500" height="200"/></li>
            <li><img src="images/01.jpg" width="500" height="200"/></li>
        </ul>
        <ol>
            <li class="current">1</li>
            <li>2</li>
            <li>3</li>
            <li>4</li>
            <li>5</li>
        </ol>

    </div>
    <div id="arr"><span id="left">&lt;</span><span id="right">&gt;</span></div>
</div>

</body>

<script src="common.js"></script>
<script src="animation.js"></script>
<script>
    /*第五步:实现自动轮播
    需求分析:(1)每隔2s,自动实现下一页点击功能
    (2)当鼠标移入box时,清除定时器,切换手动操作
    (3)当鼠标移出box时,开启定时器,切换自动轮播
        * 细节:下一页逻辑代码会执行多次,只需要放入函数中(解决代码复用的问题)

     */

    //1.获取元素
    var box = id('box');//最外面div,有边框
    var screen = document.getElementsByClassName('screen')[0];//获取图片可视div,screen
    var ul =  screen.children[0];//图片列表ul标签
    var ol =  screen.children[1];//页码标签
    var liList = ul.children;//图片li标签数组
    var olList = ol.children;//页码li标签数组
    var arr = id('arr');//上一页下一页所在的div
    var left = id('left');//上一页按钮
    var right = id('right');//下一页按钮

    //声明一个全局变量,记录当前应该显示图片的下标
    var index = 0;

    var timeID = null;//记录自动轮播定时器id

    timeID = setInterval(function (  ) {
        nextPage();
    },2000);

    //2.鼠标移入移出,显示/隐藏上一页下一页按钮
    box.onmouseover = function (  ) {
        arr.style.display = 'block';
        //清除自动轮播,切换手动操作
        clearInterval(timeID);
    }

    box.onmouseout = function (  ) {
        arr.style.display = 'none';
      timeID  = setInterval(function (  ) {
            nextPage();
        },2000);
    }

    //3.上一页下一页点击事件
    //上一页
    left.onclick = function (  ) {

        //(1)边界检测
        if(index == 0){//如果是第一张  index = 0
            //修改index为最大下标
            index = liList.length-1;
            //瞬间修改ul的位置为最后一张
            ul.style.left = -index*screen.offsetWidth + 'px';
        }
        //(2)图片下标-1
        index--;
        //(3)动画滚动图片  移动距离:  index* screen盒子的宽度
        animationMove(ul,-index*screen.offsetWidth);
        //(4)使用排他思想改变页码样式
        for(var i = 0;i<olList.length;i++){
            if(i == index){//如果页码下标与index一致,说明是当前页面,需要改变样式
                olList[i].className = 'current';
            }else{
                olList[i].className = '';
            }
        }

        //(5)如果是数组的最后一张,页码应该显示第一张
        if(index == liList.length-1){
            olList[0].className = 'current';
        }
        console.log ( index );
    }
    //下一页
    right.onclick = function (  ) {
       nextPage();
    }

    //将下一页的逻辑代码存入函数中
    function nextPage (  ) {
        //(1)边界检测
        if(index == liList.length-1){//如果index图片下标是图片数组的最大下标则不移动
            ul.style.left = '0px';//瞬间改变ul的位置为0
            index = 0;//下标复位
        }
        //(2)图片下标+1
        index++;
        //(3)动画滚动图片  移动距离:  index* screen盒子的宽度
        animationMove(ul,-index*screen.offsetWidth);

        //(4)使用排他思想改变页码样式
        for(var i = 0;i<olList.length;i++){
            if(i == index){//如果页码下标与index一致,说明是当前页面,需要改变样式
                olList[i].className = 'current';
            }else{
                olList[i].className = '';
            }
        }

        //(5)如果是数组的最后一张,页码应该显示第一张
        if(index == liList.length-1){
            olList[0].className = 'current';
        }
        console.log ( index );
    }

    //4.给页码添加点击事件
    for(var i = 0;i<olList.length;i++){
        //4.1 给每一个页码添加一个自定义属性记录下标
        olList[i].setAttribute('yemaIndex',i);
        olList[i].onclick = function (  ) {
            //4.2 获取当前页码点击的下标
            var yemaIndex = this.getAttribute('yemaIndex');
            //4.3 修改index位置为页码下标
            index = yemaIndex;
            //4.4 开始滚动
            animationMove(ul,-index*screen.offsetWidth);
            //4.5 使用排他思想改变页码样式
            for(var j = 0;j<olList.length;j++){
                if(olList[j] == this){
                    this.className = 'current';
                }else{
                    olList[j].className = '';
                }
            }
        }
    }
</script>
</html>
/*
** Create by zengjiahao on 2018/04/26
* 动画封装函数
*/

/**1.平移动画
 *
 * @param obj  要移动的元素
 * @param target  要移动的目标距离
 */
function animationMove ( obj,target ) {
    //每一次移动之前,先结束上一次的定时器
    clearInterval(obj.timeID);
    /*1.全局变量只能存储一个定时器,无法实现多个元素同时移动
    2.每一个元素在移动的时候,将定时器作为自己的属性
        * 类似于运动员在跑步的时候,每一个运动员的身上都有一个标签记录定时器,
        谁到达终点,回收谁的定时器
     */
    obj.timeID =     setInterval(function (  ) {
        //1.获取元素当前位置
        var currentLeft = obj.offsetLeft;
        //2.计算本次移动的距离
        /* 从左往右移动: 目标位置 > 当前位置    当前位置+=10
           从右往左移动: 目标位置 < 当前位置     当前位置-=10
        ifLeft:   true:从左往右  false:从右往左
         */
        var isLeft  = target>currentLeft?true:false;
        if(isLeft){
            currentLeft += 15;
        }else{
            currentLeft -= 15;
        }

        //3.边界检测
        /*从左往右true:  currentLeft < target
        从右往左false:  currentLeft > target

        边界检测思路:
            * 如果isLeft为true,current<target这个条件成立,需要移动,否则到达目的地
            * 如果isLeft为false,currentLeft > target这个条件成立,需要移动,否则到达目的地

         */
        //这个三元表达式: 如果isLeft是true则返回currentLeft<target,反之返回currentLeft>target
        if(isLeft==true?currentLeft<target:currentLeft>target){
            obj.style.left = currentLeft + 'px';
        }else{
            clearInterval(obj.timeID);//清除定时器
            obj.style.left = target + 'px';
        }

    },10);
}
;