轮播图

最终效果图

效果图.png

效果说明:

  1. 运行后六张图片自动轮播,同时下方对应的小矩形背景色变蓝。
  2. 当鼠标停放在图片上时,图片轮播动画暂停,始终显示当前图片;当鼠标移开,图片继续实现轮播动画。
  3. 当点击左边箭头时,图片右移,显示出上一张图片,同时下方对应的小矩形背景色变蓝;当点击右边箭头时,图片左移,显示下一张图片,同时下方对应的小矩形背景色变蓝。
  4. 点击下方小矩形时,仅被点击的小矩形变为蓝色,并显示对应的图片。

解析

结构层次.png

结构层次解析:

  1. 最外层是一个大的div,类名为slide。
  2. slide里面包含了上下两个div:上面div类名为slide_scroll;下面div类名为slide_ctrl。
  3. slide_scroll里面是一个类名为slide_main的div,该div宽度为两个图片宽度的总和。
  4. slide_main里面包含了六个类名为slide_pic的div,用来存放img。
  5. slide_ctrl里面是八个span标签,其中两个是左右箭头,剩下六个是下方的小矩形(小矩形span为js中动态创建,根据图片的张数来生成相同个数的span标签)。

运动思想:
初始状态为:左边一张图片,右边紧挨着叠放了五张图片。

  • 当点击左边箭头时,当前图片右移,上一张图片马上定位至当前可视位置的左边,然后立即缓动动画移入当前可视位置,同时对应的矩形变为蓝色。
  • 当点击右边箭头时,当前图片左移,下一张图片马上定位至当前可视位置的右边,然后立即缓动动画移入当前可视位置,同时对应的矩形变为蓝色。
  • 当点击小矩形时,被点击的矩形变蓝
  • 被电击的小矩形的index值大于当前显示图片的角标值时,当前图片左移,将index值赋值为下一个当前图片,首先将该图片定位至可视位置的右边,再立即缓动动画移至当前可视位置
  • 被电击的小矩形的index值小于当前显示图片的角标值时,当前图片右移,将index值赋值为下一个当前图片,首先将该图片定位至可视位置的左边,再立即缓动动画移至当前可视位置

代码以及注释

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>轮播图</title>

    <style>
        *{
            margin: 0;
            padding: 0;
            border: none;
        }
        .slide{
            width: 310px;
            height: 260px;
            margin: 100px auto;
            position: relative;
            overflow: hidden;
        }
        .slide .slide_scroll{
            width: 310px;
            height: 220px;
            position: relative;
        }
        .slide .slide_scroll .slide_main{
            width: 620px;
            height: 220px;
        }
        .slide .slide_scroll .slide_main .slide_pic{
            width: 310px;
            height: 220px;
            position: absolute;
            left: 0;
            top: 0;
        }
        .slide .slide_ctrl{
            width: 310px;
            height: 40px;
            text-align: center;
        }
        .slide .slide_ctrl .slide_left,.slide .slide_ctrl .slide_right{
            width: 20px;
            height: 34px;
            position: absolute;
            top: 50%;
            margin-top: -34px;
            background: url("images/icon.png") no-repeat;
        }
        .slide .slide_ctrl .slide_left{
            left: 0;
            background-position: 0 0;
        }
        .slide .slide_ctrl .slide_right{
            right: 0;
            background-position: -9px -45px;
        }
        .slide_item{
            width: 20px;
            height: 5px;
            background: url("images/icon.png") -24px -790px;
            display: inline-block;
            margin: 5px;
            text-indent:20em;
        }
        .curr{
            background-position:0 -770px;
        }
    </style>
</head>
<body>
    <div class="slide">
        <div class="slide_scroll">
            <div class="slide_main">
                <div class="slide_pic">
                    <a href="#">
                        ![](images/1.jpeg)
                    </a>
                </div>
                <div class="slide_pic">
                    <a href="#">
                        ![](images/2.jpeg)
                    </a>
                </div>
                <div class="slide_pic">
                    <a href="#">
                        ![](images/3.jpeg)
                    </a>
                </div>
                <div class="slide_pic">
                    <a href="#">
                        ![](images/4.jpeg)
                    </a>
                </div>
                <div class="slide_pic">
                    <a href="#">
                        ![](images/5.jpeg)
                    </a>
                </div>
                <div class="slide_pic">
                    <a href="#">
                        ![](images/6.jpeg)
                    </a>
                </div>
            </div>
        </div>
        <div class="slide_ctrl">
            <span class="slide_left"></span>

            <!--<span class="slide_item"></span>
            <span class="slide_item"></span>
            <span class="slide_item"></span>
            <span class="slide_item"></span>
            <span class="slide_item"></span>
            <span class="slide_item"></span>-->

            <span class="slide_right"></span>
        </div>
    </div>

    <script>
        window.onload = function () {
            var slide = document.getElementsByTagName('div')[0];
            var slide_scroll = slide.children[0];
            var slide_main   = slide_scroll.children[0];
            var slide_pic    = slide_main.children;
            var slide_ctrl   = slide.children[1];
            var slide_spans  = slide_ctrl.children;
            var pic_w = slide_pic[0].offsetWidth;

            //根据图片的个数添加图片下方的小矩形
            for(var i=0; i<slide_pic.length; i++) {
                var slide_item = document.createElement('span');
                slide_item.className = 'slide_item';
                /*一直向slide_ctrl的第一个子标签前插入
                 *(新插入的节点总会成为第一个子标签),
                 *相当于倒序插入,所以innerHTML值为slide_pic.length - i - 1
                 *(0,1,2,3,4,5) */
                slide_item.innerHTML = slide_pic.length - i - 1;
                slide_ctrl.insertBefore(slide_item,slide_ctrl.children[1]);
            }

            //给第一个小矩形设置背景色
            slide_ctrl.children[1].className = 'slide_item curr';
            /* 给图片定位,第一张图片在左边,
            * 剩余的所有图片都绝对定位叠在右边*/
            for(var i=1; i<slide_pic.length; i++) {
                slide_pic[i].style.left = pic_w + 'px';
            }

            //点击事件
            var iNow = 0;
            for(var i=0; i<slide_spans.length; i++) {
                var mySpan = slide_spans[i];
                mySpan.onclick = function () {
                    if(this.className == 'slide_left') {//点击左边箭头
                        buffer(slide_pic[iNow],{left:pic_w});  //先将当前图片右移
                        iNow --;              //找到上一张图片的角标值设为当前
                        if(iNow < 0){
                            iNow = slide_pic.length - 1;
                        }
                        slide_pic[iNow].style.left = -pic_w + 'px';//上一张图片移到左边
                        buffer(slide_pic[iNow],{left:0});//动画将上一张图片移到当前位置
                    } else if(this.className == 'slide_right'){//点击右边箭头
                        buffer(slide_pic[iNow],{left:-pic_w});
                        iNow ++;
                        if(iNow > slide_pic.length-1){
                            iNow = 0;
                        }
                        slide_pic[iNow].style.left = pic_w + 'px';
                        buffer(slide_pic[iNow],{left:0});
                    } else {//点击下面一排小矩形
                        //注意点:this.innerHTML是字符串类型,所以必须将其强制转换为数值类型,避免后面用到iNow出现错误。
                        var index = parseInt(this.innerHTML);
                        if(index > iNow){
                            buffer(slide_pic[iNow],{left:-pic_w});
                            iNow = index;//及时更新iNow值
                            slide_pic[iNow].style.left = pic_w + 'px';
                            buffer(slide_pic[iNow],{left:0});
                        }else if(index < iNow) {
                            buffer(slide_pic[iNow],{left:pic_w});
                            iNow = index;
                            slide_pic[iNow].style.left = -pic_w + 'px';
                            buffer(slide_pic[iNow],{left:0});
                        }
                    }
                    changeIndex();
                }

            }
            //运行后自动轮播
            var timer = setInterval(autoPlay,1000);
            slide.onmouseover = function () {
                clearInterval(timer);
            };
            slide.onmouseout = function () {
                timer = setInterval(autoPlay,1000);
            };

            //改变下方小矩形对应图片显示背景色
            function changeIndex(){
                for(var i=1; i<slide_spans.length-1; i++){
                    slide_spans[i].className = 'slide_item';
                }
                slide_spans[iNow+1].className = 'slide_item curr';
            }
            //自动轮播的函数
            function autoPlay(){
                buffer(slide_pic[iNow],{left:-pic_w});
                iNow ++;
                if(iNow > slide_pic.length-1){
                    iNow = 0;
                }
                slide_pic[iNow].style.left = pic_w + 'px';
                buffer(slide_pic[iNow],{left:0});

                changeIndex();
            }

          function buffer(obj,json,fn) {
    clearInterval(obj.timer);
    //初始值、速度、目标值
    var begin = 0;
    var speed = 0;
    var target = 0;

    obj.timer = setInterval(function () {
        var flag = true;
        for(var key in json) {
            //当需求为更改透明度时需另外判断
            if('opacity' == key) {
                begin = parseInt(parseFloat(getAtributeValue(obj,key)) * 100);
                target = parseInt(json[key] * 100);
            } else if('scrollTop' == key){
                begin = obj.scrollTop;
                target = parseInt(json[key]);
            }else {
                begin = parseInt(getAtributeValue(obj,key));
                target = parseInt(json[key]);
            }
            //速度为正值时需向上取值,速度为负值时需向下取值
            speed = target > begin ? Math.ceil((target - begin) * 0.2) : Math.floor((target - begin) * 0.2);

            if('opacity' == key) {
                obj.style.opacity = parseFloat((begin + speed) / 100);
                obj.style.filiter = 'alpha(opactiy:' + (begin + speed) + ')';
            } else if('scrollTop' == key) {
                obj.scrollTop = begin + speed;
            } else if('zIndex' == key){
                obj.style.zIndex = json[key];
            }else {
                obj.style[key] = begin + speed + 'px';
            }
            //为了避免当其中一个属性到达目标值的情况发生,需声明一个布尔值变量记录,只要有一个属性未能
            //到达目标值,该布尔值就为false,当且仅当为true时,清除定时器。
            if(begin != target) {
                flag = false;
            }
        }
        if(flag) {
            clearInterval(obj.timer);
            if(fn){
                fn();
            }
        }
    },30);
}
        }
    </script>
</body>
</html>

注意点:

  1. slide_main类的div负责滚动,不负责定位,因此slide_pic定位在slide_scroll上;slide_left和slide_right(即两个箭头)定位在总的大盒子上。
  2. 小矩形的个数由图片张数决定,所以在js中动态创建并添加。
  3. 及时更新iNow值,该值表示当前显示图片的角标值。
  4. buffer函数为一个简单的缓动运动框架。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容