[未完结]图片轮播图

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();
        }

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,172评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,346评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,788评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,299评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,409评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,467评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,476评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,262评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,699评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,994评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,167评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,827评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,499评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,149评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,387评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,028评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,055评论 2 352

推荐阅读更多精彩内容

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