[未完结]图片轮播图

demo效果:
css布局:

    * {
           margin: 0;
           padding: 0;
           text-decoration: none;
       }
       body {
           padding: 20px;
       }
       #container {
           width: 600px;
           height: 400px;
           border: 3px solide #333;
           overflow: hidden;
           position: relative;
       }
       #list {
           background-color: red;
           width: 3000px;  /* 7*600 = 4200px */
           height: 400px;  /*一共有七张图(600*400)*/
           position: absolute;
           z-index: 1;
       }
       #list img {
           float: left;
       }
       #buttons {
           position: absolute;
           height: 10px;
           width: 100px;
           z-index: 2;
           bottom: 20px;
           left: 250px;
       }
       #buttons span {
           cursor: pointer;
           float: left;
           border: 1px solid #fff;
           width: 10px;
           height: 10px;
           border-radius: 50%;
           background: #333;
           margin-right: 5px;
       }
       #buttons .on {
           background: orangered;
       }
       .arrow {
           cursor: pointer;
           display: none;
           line-height: 39px;
           text-align: center;
           font-size: 36px;
           font-weight: bold;
           width: 40px;
           height: 40px;
           position: absolute;
           z-index: 2;
           top: 180px;
           background-color: rgba(0, 0, 0, .3);
           color: #fff;
       }
       .arrow:hover {
           background-color: rgba(0, 0, 0, .7);
       }
       #container:hover .arrow {
           display: block;
       }
       #prev {
           left: 20px;
       }

       #next {
           right: 20px;
       }

其次html的大概结构:

<div id="container">
   <!-- 这里必须要定位list的left位置为0px -->
   <div id="list" style="left: 0px;">
       ![](img/1.jpg)
       ![](img/2.jpg)
       ![](img/3.jpg)
       ![](img/4.jpg)
       ![](img/5.jpg)
   </div>
   <div id="buttons">
       <span index="1" class="on"></span>
       <span index="2"></span>
       <span index="3"></span>
       <span index="4"></span>
       <span index="5"></span>
   </div>
   <a href="javascript:;" id="prev" class="arrow"><</a>
   <a href="javascript:;" id="next" class="arrow">></a>
</div>

轮播之箭头切换 & 无限滚动 的实现:
代码如下:

window.onload = function() {
           // 获取最外层容器container
           var container = document.getElementById('container');
           // 获取包裹图片的list容器
           var list = document.getElementById('list');
           // 获取包裹橙点的span
           var buttons = document.getElementById('buttons').getElementsByTagName('span');
           var prev = document.getElementById('prev');
           var next = document.getElementById('next');

           /**
            * [animate: 箭头控制图片位置函数]
            * @param  {[number]} offset [位移的数字]
            */
           function animate(offset) {
               // 用newLeft存放加上传入offset需要改变的新的left值
               var newLeft = parseInt(list.style.left) + offset;
               list.style.left = newLeft + 'px';

               if (newLeft > 0) {
                   list.style.left = -2400 + 'px';
               }
               if (newLeft < -2400) {
                   list.style.left = 0 + 'px';
               }
           }

           next.onclick = function() {
               animate(-600);
           }
           prev.onclick = function() {
               animate(600);
           }
       }

上面的效果完成之后,会有一个问题,就是最下面的原点不会随着图片的变化,而当前高亮。解决方案:
index为当前原点span中的的索引,并且我们要清楚之前的高亮的样式。
代码如下:

var  index = 1;

/**
* [showButton 下面的小圆点按钮]
*/
function showButton() {
   // 遍历清除重复的原点样式
   for (var i = 0; i < buttons.length; i++) {
       if (buttons[i].className == 'on') {
           buttons[i].className = '';
           break;
       }
   }
   // 取到的button是从0开始计数的,但是我们定义的index的初试是从1开始,故要减去1
   buttons[index - 1].className = 'on';  
}

但是到了这里,会有一个小问题,就是当我们点击上面的左右箭头滑动到第一张图片和最后一张图片所对应的原点的时候,我们再往前或者往后的时候,就不能正常高亮当前原点了。
造成这种现象的主要原因是因为:我们定义了index,并且随着pre,和next的点击,它会一直增加或者减少,已经为0的时候再减就变成了负数了,已经为4(对应第五张图)的时候,还是会继续增加变成5。然而我们圆点对应的span的索引只有1到5,所以这里我们还应该对临界的两个span做一下判断。
代码如下:

next.onclick = function() {
    if (index == 5) {  // 如果到了最后一个圆点
        index = 1;  // 将index置1
    }
    else {
        index += 1;  // 只要不是最后一个则加1
    }

    showButton();  // 原代码不变
    animate(-600);  // 原代码不变
}
prev.onclick = function() {
    if (index == 1) {  //如果已经到了第一个圆点
        index = 5;  // 直接跳到最后一个
    }
    else {
        index -= 1;  // 否则可以继续累减
    }

    showButton();  // 原代码不变
    animate(600);  // 原代码不变
}

经过上面的步骤,此时的代码如下:

        window.onload = function() {
            // 获取最外层容器container
            var container = document.getElementById('container');
            // 获取包裹图片的list容器
            var list = document.getElementById('list');
            // 获取包裹橙点的span
            var buttons = document.getElementById('buttons').getElementsByTagName('span');
            var prev = document.getElementById('prev');
            var next = document.getElementById('next');
            var index = 1;

            /**
             * [showButton 下面的小圆点按钮]
             */
            function showButton() {
                // 遍历清除重复的原点样式
                for (var i = 0; i < buttons.length; i++) {
                    if (buttons[i].className == 'on') {
                        buttons[i].className = '';
                        break;
                    }
                }
                buttons[index - 1].className = 'on';
            }

            /**
             * [animate: 箭头控制图片位置函数]
             * @param  {[number]} offset [位移的数字]
             */
            function animate(offset) {
                // 用newLeft存放加上传入offset需要改变的新的left值
                var newLeft = parseInt(list.style.left) + offset;
                list.style.left = newLeft + 'px';

                if (newLeft > 0) {
                    list.style.left = -2400 + 'px';
                }
                if (newLeft < -2400) {
                    list.style.left = 0 + 'px';
                }
            }

            next.onclick = function() {
                if (index == 5) {
                    index = 1;
                }
                else {
                    index += 1;
                }

                showButton();
                animate(-600);
            }
            prev.onclick = function() {
                if (index == 1) {
                    index = 5;
                }
                else {
                    index -= 1;
                }

                showButton();
                animate(600);
            }
        }

实现点击下方圆点点击更新对应的图片

for (var i = 0; i < buttons.length; i++) {
    buttons[i].onclick = function() {
        // 获取当前的index属性里面的数字
        var myIndex = parseInt(this.getAttribute('index'));
        // 计算出图片要移动的距离
        var offset = -600 * (myIndex - index);

        animate(offset);  //调用animate函数
        index = myIndex;  // 更新index的值
        showButton();  //调用函数使得当前圆点高亮
    }
}

虽然以上的函数已经可以实现功能了,但是,如果我们点击的按钮是同一个,也就是不变,按照上面的函数,for循环还是会被重新执行一次。所以我们可以在点击事件里加上一个if判断。
代码如下:

for (var i = 0; i < buttons.length; i++) {
    buttons[i].onclick = function() {
        if (this.className == 'on') {  // 如果点击的原点已经高亮
            return;  // 直接return,下面的代码也不执行了
        }

        var myIndex = parseInt(this.getAttribute('index'));
        var offset = -600 * (myIndex - index);

        animate(offset); 
        index = myIndex;  
        showButton(); 
    }
}

PS:
下面这个函数,能够获取一个元素的任意 CSS 属性值。


function getStyle(element, attr) {

   if(element.currentStyle) {

       return element.currentStyle[attr];

   } else {

       return getComputedStyle(element, false)[attr];

   }

}
// 比如,本例中如果想获得 lists 的 left 属性值,只需要 getStyle(lists,"left")就可以啦。

加上定时器:

        window.onload = function() {
            // 获取最外层容器container
            var container = document.getElementById('container');
            // 获取包裹图片的list容器
            var list = document.getElementById('list');
            // 获取包裹橙点的span
            var buttons = document.getElementById('buttons').getElementsByTagName('span');
            var prev = document.getElementById('prev');
            var next = document.getElementById('next');
            var index = 1;
            var  animated = false;

            /**
             * [showButton 下面的小圆点按钮]
             */
            function showButton() {
                // 遍历清除重复的原点样式
                for (var i = 0; i < buttons.length; i++) {
                    if (buttons[i].className == 'on') {
                        buttons[i].className = '';
                        break;
                    }
                }
                buttons[index - 1].className = 'on';
            }

            /**
             * [animate: 控制图片位置函数]
             * @param  {[number]} offset [位移的数字]
             */
            function animate(offset) {
                animated = true;
                // 用newLeft存放加上传入offset需要改变的新的left值
                var newLeft = parseInt(list.style.left) + offset;
                var time = 300;   // 位移总时间
                var interval = 10; // 位移间隔时间
                var speed =  offset / (time / interval);  // 每次位移量

                /**
                 * [go:位移的判断以及什么时候做位移]
                 */
                function go() {
                    if ((speed > 0 && parseInt(list.style.left) < newLeft)
                        || (speed < 0 && parseInt(list.style.left) > newLeft)) {
                        list.style.left = parseInt(list.style.left) + speed + 'px';
                        setTimeout(go, interval);  // 递归
                    }
                    else {
                        animated = false;
                        list.style.left = newLeft + 'px';

                        if (newLeft > 0) {
                            list.style.left = -2400 + 'px';
                        }
                        if (newLeft < -2400) {
                            list.style.left = 0 + 'px';
                        }
                    }
                }
                go();
            }

            next.onclick = function() {
                if (index == 5) {
                    index = 1;
                }
                else {
                    index += 1;
                }

                showButton();

                if (!animated) {
                    animate(-600);
                }
            }
            prev.onclick = function() {
                if (index == 1) {
                    index = 5;
                }

                else {
                    index -= 1;
                }

                showButton();
                if (!animated) {
                    animate(600);
                }
            }

            // 实现点击下面的按钮,图片也跟着变换
            // 遍历所有的圆点,给他们一个点击事件
            for (var i = 0; i < buttons.length; i++) {
                buttons[i].onclick = function() {
                    if (this.className == 'on') {  // 如果点击的原点已经高亮
                        return;  // 直接return,下面的代码也不执行了
                    }
                    // 获取当前的index属性里面的数字
                    var myIndex = parseInt(this.getAttribute('index'));
                    // 计算出图片要移动的距离
                    var offset = -600 * (myIndex - index);

                    if (!animated) {
                        animate(offset);  //调用animate函数
                    }
                    index = myIndex;  // 更新index的值
                    showButton();  //调用函数使得当前圆点高亮
                }
            }
        }

加上自动播放函数:

        window.onload = function() {
            // 获取最外层容器container
            var container = document.getElementById('container');
            // 获取包裹图片的list容器
            var list = document.getElementById('list');
            // 获取包裹橙点的span
            var buttons = document.getElementById('buttons').getElementsByTagName('span');
            var prev = document.getElementById('prev');
            var next = document.getElementById('next');
            var index = 1;
            var  animated = false;
            var timer;  //存放定时器

            /**
             * [showButton 下面的小圆点按钮]
             */
            function showButton() {
                // 遍历清除重复的原点样式
                for (var i = 0; i < buttons.length; i++) {
                    if (buttons[i].className == 'on') {
                        buttons[i].className = '';
                        break;
                    }
                }
                buttons[index - 1].className = 'on';
            }

            /**
             * [animate: 控制图片位置函数]
             * @param  {[number]} offset [位移的数字]
             */
            function animate(offset) {
                animated = true;
                // 用newLeft存放加上传入offset需要改变的新的left值
                var newLeft = parseInt(list.style.left) + offset;
                var time = 300;   // 位移总时间
                var interval = 10; // 位移间隔时间
                var speed =  offset / (time / interval);  // 每次位移量

                /**
                 * [go:位移的判断以及什么时候做位移]
                 */
                function go() {
                    if ((speed > 0 && parseInt(list.style.left) < newLeft)
                        || (speed < 0 && parseInt(list.style.left) > newLeft)) {
                        list.style.left = parseInt(list.style.left) + speed + 'px';
                        setTimeout(go, interval);  // 递归
                    }
                    else {
                        animated = false;
                        list.style.left = newLeft + 'px';

                        if (newLeft > 0) {
                            list.style.left = -2400 + 'px';
                        }
                        if (newLeft < -2400) {
                            list.style.left = 0 + 'px';
                        }
                    }
                }
                go();
            }

            function play() {
                timer = setInterval(function() {
                    next.onclick();
                }, 3000);
            }

            function stop() {
                clearInterval(timer);
            }

            next.onclick = function() {
                if (index == 5) {
                    index = 1;
                }
                else {
                    index += 1;
                }

                showButton();

                if (!animated) {
                    animate(-600);
                }
            }
            prev.onclick = function() {
                if (index == 1) {
                    index = 5;
                }

                else {
                    index -= 1;
                }

                showButton();
                if (!animated) {
                    animate(600);
                }
            }

            // 实现点击下面的按钮,图片也跟着变换
            // 遍历所有的圆点,给他们一个点击事件
            for (var i = 0; i < buttons.length; i++) {
                buttons[i].onclick = function() {
                    if (this.className == 'on') {  // 如果点击的原点已经高亮
                        return;  // 直接return,下面的代码也不执行了
                    }
                    // 获取当前的index属性里面的数字
                    var myIndex = parseInt(this.getAttribute('index'));
                    // 计算出图片要移动的距离
                    var offset = -600 * (myIndex - index);

                    if (!animated) {
                        animate(offset);  //调用animate函数
                    }
                    index = myIndex;  // 更新index的值
                    showButton();  //调用函数使得当前圆点高亮
                }
            }

            container.onmouseover = stop;
            container.onmouseout = play;

            play();
        }

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 179,058评论 25 709
  • 原理 图片轮播原理:将一系列大小相等的图片平铺,利用css布局只显示一张图片,其他图片隐藏,通过计算偏移量利用定时...
    黎贝卡beka阅读 2,323评论 1 2
  • ¥开启¥ 【iAPP实现进入界面执行逐一显】 〖2017-08-25 15:22:14〗 《//首先开一个线程,因...
    小菜c阅读 7,335评论 0 17
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,569评论 19 139
  • 从学校毕业光着脚在社会游走也有近7年的时间,回想一路走来,虽不说跌跌撞撞,但也跳了不少坑。 踏进了社会这个圈子,还...
    奶油青草阅读 1,210评论 2 11

友情链接更多精彩内容