今天在网上看到有人说到轮播图。我自己还没写过,所以简单实现一个。
GitHub链接:https://github.com/cyjsysu/mi...

1. 效果

轮播图.gif

2. 实现方案

我首先想到了三种可能可以实现的方法。

  1. 设一个div标签,定时更改背景图和链接。
  2. 设置5个相同的div,分别有不同的背景图。定时更改每个div的display(block/none)。
  3. 类似2。每次调整div的z-index。

然后就是老规矩,打开B站,有样学样。通过B站的HTML可以发现B站首页的轮播图用的就是第三种方法。
为了进一步熟悉面向对象,我在小项目里用了class。
B站zIndex.PNG

3. 轮播

这里有5张图片,先使 position: absolute ,不考虑js并且不做特别设置的前提下,显示在上面的是最后一张图。为了让文件开始加载时就显示第一张图,而不是最后一张,我设置第一张图的z-index为1,其余为0。
类的成员变量定义如下。通过设置定时器,让index在0到4变动,每次设置相应div的z-index为++maxZ即可。比较简单。

class Carousel {  
    constructor() {  
        this.index = 0; //当前显示图片索引  
        this.maxZ = 1; //当前图片最大z-index  
        this.timer = null; //定时器  
  }
}

4. 更改图片的小圆点

这个很简单,用事件委托实现即可。给id为trigger的结点绑定一个onclick事件。触发后判断是点击了哪个圆点,再做相应处理即可。
这里我多做了一点。之前在某个著名网站上我对其轮播图的体验非常差,因为我切换了图片后,他的定时器触发,马上又跳转到了下一张。所以我这里点击后会取消掉现有的定时器,处理完毕后再重置。这就避免了以上问题。

5. 碰到的坑

5.1 用class创建对象时this的指向问题

使用回调函数时出现问题。像下面这种情况,this指向window。

this.timer = setInterval(function (){}, 1000);

可使用bind解决问题。

this.timer = setInterval(function (){}.bind(this), 1000);

5.2 代码执行时机存在问题

开始时,使用document.getElementById会返回undefined。我认为问题是body未加载完就执行了js代码。用window.onload即可解决问题。

6. 全部代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>carousel</title>
    <style>
        #carousel {
            width: 800px;
            height: 450px;
            position: relative;
            margin: 0 auto;
        }

        #slide {
            width: 100%;
            height: 100%;
            position: absolute;
        }

        #slide .item {
            width: 100%;
            height: 100%;
            position: absolute;
            z-index: 0;
        }

        #slide .item img {
            width: 100%;
            height: 100%;
        }

        #trigger {
            width: 260px;
            height: 40px;
            /*background-color: red;*/
            left: 500px;
            top: 400px;
            position: absolute;
            z-index: 2147483647;
        }

        #trigger span {
            width: 20px;
            height: 20px;
            margin-left: 25px;
            background-color: white;
            border-radius: 50%;
            z-index: 2147483647;
            display: inline-block;
        }

        #trigger .on {
            background-image: url("./img/吃豆人.png");
            background-repeat: no-repeat;
            background-size: cover;
            background-color: transparent;
            transform: scale(1.8);
            /*background-color: red;*/
        }
    </style>
    <script>

        window.onload = function () {
            var carouselObj = new Carousel();
        };


        class Carousel {
            constructor() {
                this.index = 0;  //当前显示图片索引
                this.maxZ = 1;  //当前图片最大z-index
                this.timer = null;  //定时器

                this.init();  //初始化
            }

            init() {
                this.setTimer();  //设置定时器

                //绑定事件,当点击圆点时跳转到相应图片
                var oTrigger = document.getElementById("trigger");
                oTrigger.onclick = function (evt) {
                    clearInterval(this.timer);  //先暂停定时器

                    var oImgItems = document.getElementById("slide").getElementsByClassName("item");
                    var oTriggerSpan = document.getElementById("trigger").getElementsByTagName("span");

                    //确定点击的圆点索引
                    var target = evt.target;
                    var toIndex = -1;
                    for (var i = 0; i < oTriggerSpan.length; i++) {
                        if (oTriggerSpan[i] == target)
                            toIndex = i;
                    }

                    oTriggerSpan[this.index].classList.remove("on");
                    this.index = toIndex;
                    oTriggerSpan[this.index].classList.add("on");
                    oImgItems[this.index].style.zIndex = ++this.maxZ;

                    this.setTimer();  //恢复定时器
                }.bind(this);

            }

            setTimer() {
                clearInterval(this.timer);
                //console.log([this.index, this.maxZ]);

                this.timer = setInterval(function () {
                    var oImgItems = document.getElementById("slide").getElementsByClassName("item");
                    var oTriggerSpan = document.getElementById("trigger").getElementsByTagName("span");

                    oTriggerSpan[this.index].classList.remove("on");
                    this.index = (this.index + 1) % oImgItems.length;
                    oTriggerSpan[this.index].classList.add("on");

                    oImgItems[this.index].style.zIndex = ++this.maxZ;
                }.bind(this), 1000);
            }

        }

    </script>
</head>
<body>
<div id="carousel">
    <div id="slide">
        <div class="item" style="z-index: 1">
            <a href="#">
                <img src="./img/蜘蛛侠.jpg" alt="蜘蛛侠">
            </a>
        </div>
        <div class="item">
            <a href="#">
                <img src="./img/飞屋环游记.jpg" alt="飞屋环游记">
            </a>
        </div>
        <div class="item">
            <a href="#">
                <img src="./img/小黄人.jpg" alt="小黄人.">
            </a>
        </div>
        <div class="item">
            <a href="#">
                <img src="./img/宝可梦.jpg" alt="宝可梦">
            </a>
        </div>
        <div class="item">
            <a href="#">
                <img src="./img/海绵宝宝.jpg" alt="海绵宝宝">
            </a>
        </div>
    </div>
    <div id="trigger">
        <span class="on"></span>
        <span></span>
        <span></span>
        <span></span>
        <span></span>
    </div>

</div>
</body>
</html>

PANDAS
1 声望0 粉丝