轮播图简单实现

本文介绍了使用JavaScript实现轮播图的详细步骤,包括创建静态界面,通过改变ul的left属性实现图片切换,利用计数器和计时器实现自动轮播,以及解决轮播过程中的各种问题,如图片不连续、导航与图片不匹配、动画冲突等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如何实现轮播图?

根据视频尚硅谷JavaScript视频整理得到。
思路:
在这里插入图片描述

ul是将所有图片平铺,不断改变ul的left属性,使得图片得以轮转
div可以设置属性:overflow:hidden 是超出div范围的图片隐藏

创建静态界面:

 <style>
        *{
            margin: 0;
            padding: 0;
        }
        #outer{
            background-color: aquamarine;
            height: 332px;
            margin: 50px auto;
            overflow: hidden;
            position: relative;
            width: 520px;
            padding: 10px 0px;
        }
        #imgList{
            /*width写死了不好*/
            /*width: 2500px;*/
            /*去除项目符号*/
            list-style: none;
            position: absolute;
            left: -520px;
            /*每向左移动530,到下面一张图*/
        }
        #imgList li{
            float: left;
            margin: 0 10px;
        }
        #navDiv{
            position: absolute;
            bottom: 5px;
            /*left可以利用js设定*/
            /*left=(outerWidth-navDivWidth)/2*/
        }
        #navDiv a{
            float: left;
            width: 10px;
            height: 10px;
            background-color: cadetblue;
            margin-left:5px;
            opacity: 0.7;
            /*兼容IE8*/
            filter: alpha(opacity=70);
        }
        #navDiv a:hover{
            background-color: yellow;
        }
    </style>
<body>
<div>
    <div id="outer">
        <ul id="imgList">
            <li>
                <img src="img/1.jpg">
            </li>
            <li>
                <img src="img/2.jpg">
            </li>
            <li>
                <img src="img/3.jpg">
            </li>
            <li>
                <img src="img/4.jpeg">
            </li>
        </ul>
        <div id="navDiv">
            <a href="javascript:;"></a>
            <a href="javascript:;"></a>
            <a href="javascript:;"></a>
            <a href="javascript:;"></a>
        </div>
    </div>
</div>
</body>

静态界面创建成功界面如下:
在这里插入图片描述
这里注意imgList(ul)的长度和navDiv(超链接)的位置没有通过CSS静态设置,通过JS动态设置可以方便后续添加图片

 //设置ul宽度
            var imgList = document.getElementById("imgList");
            var imgArr = document.getElementsByTagName("img");
            // 图片长度加上margin的长度
            imgList.style.width = 530 * imgArr.length + "px";

            //设置下面导航小点的位置
            // 父级元素div的长度减去小点的长度
            var outer = document.getElementById("outer");
            var navDir = document.getElementById("navDiv");
            navDir.style.left = (outer.offsetWidth - navDir.offsetWidth) / 2 + "px";

            // 默认初始索引为0
            var index = 0;
            var allA = document.getElementsByTagName("a");
            allA[index].style.backgroundColor = "yellow";

通过上面的代码,静态页面显示完毕,下面是添加JS代码使得图片轮播起来

  1. 点击导航栏(超链接)使得图片可以切换图片
 //点击不同的超链接,切换到不同的图片
            for (var i = 0; i < allA.length; i++) {
                //为每一个超链接添加num属性
                allA[i].num = i;
                allA[i].onclick = function () {
                    index = this.num;
                    //切换图片
                    //第一张 0 0 第二张 1 -520
                    //静态改变图片
                     imgList.style.left = index * -520 +"px"
                    //修改超链接
                    setA();
                }
            }

这里是静态改变ul的left属性值,使得图片可以切换但是并未达到轮播效果。
下面是用超链接的颜色改变,写在setA()函数里面,在上面的代码中进行调用,实现点击不同的超链接,出现相应的图片并且颜色出现变化。

这里注意:allA[i].style.backgroundColor = ""设置为空串的原因是,js设置的样式为内联样式,会覆盖掉之前在CSS样式表里面设置的样式,使得hover失效,所以这里使用空串,在遍历后,颜色不发生变化,只是在index中设置变化后的样式,hover有效。。

//创建方法使得点击的超链接变色其他的不变
            function setA() {
                for (var i = 0; i < allA.length; i++) {
                    // 将所有的遍历背景颜色设置为本色
                    // 这样写会使得hover失效,内联样式会覆盖样式表的样式
                    // allA[i].style.backgroundColor = "cadetblue";
                    // 写成空串就不会覆盖
                    allA[i].style.backgroundColor = ""
                }
                // 将选中的超链接变色
                allA[index].style.backgroundColor = "yellow";

            }
  1. 添加计数器使得图片轮播,修改步骤一的函数,现在点击导航栏可以实现图片轮播
    这里要介绍视频之前写的一个很方便的元素移动的函数
 // 获取当前元素的位置
            function getstyle(obj, name) {
                if (window.getComputedStyle) {
                    return getComputedStyle(obj, null)[name];
                } else {
                    return obj.currentScript[name];
                }
            }
// 元素移动函数
            //   obj:移动元素
            //   target:移动范围目标位置
            //   speed:移动速度(正负)
            //   direction:移动方向
            //   callback:回调函数,动画执行完毕后执行
            function move(obj, target, speed, direction,callback) {
                clearInterval(obj.timer);
                var current = parseInt(getstyle(obj, direction));
                if (current > target) {
                    speed = -speed;
                }
                obj.timer = setInterval(function () {
                    var oldValue = parseInt(getstyle(obj, direction));
                    var newValue = oldValue + speed;
                    if ((speed < 0 && newValue < target) || (speed > 0 && newValue > target)) {
                        newValue = target;
                    }
                    obj.style[direction] = newValue + "px";
                    if (newValue == target) {
                        clearInterval(obj.timer);
                        callback();
                    }
                }, 30);
            }

move()可以将代码全部复制过去,添加元素,目标位置,方向,速度,回调函数,在调用函数,即可实现。逻辑很简单:获取元素当前位置,在当前位置上进行相应的改变。其中的direction其实不完全是方向,可以设置为left,top,width,height都可以。

修改第二步的静态切换图片的方法
注释掉imgList.style.left = index * -520 +“px”,调用move函数,回调函数暂时空着,调用setA()函数改变导航栏(超链接)

                    //静态改变图片
                    // imgList.style.left = index * -520 +"px"
                    //加上计时器
                    move(imgList, -520 * index, 10, "left",function () {
                        
                    });
                    //修改超链接
                    // this.style.backgroundColor = "yellow";
                    setA();
  1. 实现图片自动轮播
    index实现自增,开启计时器,调用move()函数实现图片自动轮播。
    但是现在仍存在问题:
  • 在轮播到最后一张的时候,index自动为0,图片向第一张迅速移动,在最后一张的时候图片轮播不连续。
  • 图片轮播的时候,超链接和图片不一致
  • 图片自动轮播的动画和点击超链接图片切换动画会出现冲突
            function auto() {
                //开启计时器
                setInterval(function () {
                    //索引自增
                    index++;
                    //判断index的值不能超过最大值
                    if (index == imgArr.length){
                        index = 0;
                    }
                   move(imgList,-520*index,10,"left",function () { 
                    }
                },3000)
            }
            auto()
  1. 解决图片轮播到最后一张向前跳跃问题
    解决办法一 :在最后一张图片再添加第一张图片
.........
            <li><img src="img/4.jpeg"></li>
            <li><img src="img/1.jpg"></li>

结果:换汤不换药 ,图片在切换第二张的时候还是不连贯
解决办法二:在auto()函数添加if语句,在最后一张的时候,设置imgList.style.left=0;
结果:在倒数第一张向第一张切换的时候,没有出现动画,图片直接变化

将上面两种方法结合可以得到解决问题的办法
图解如下:
在这里插入图片描述
在最后一张的时候,由于后面仍有第一张,所以图片继续向后轮播,但是有imgList.style.left = 0;所以ul向前跳转,但是由于图片一样,造成连续切换的假象。这里可以将图片顺序改为最后一张图片接其他图片,就会发现中间的图片切换

.........
            <li><img src="img/4.jpeg"></li>
            <li><img src="img/2.jpg"></li>

在setA()的函数中添加

 //判断索引是否为最后一张图片
                if (index >= imgArr.length -1){
                    index = 0;
                    //此时显示最后一张但是和第一张一样
                    imgList.style.left = 0;
                }

此时可以完美解决最后一张图片跳跃问题

  1. 解决自动轮播图片和超链接不匹配问题
    这里就是在auto()函数中合理调用setA()的问题。由于auto()函数中实现图片轮播的函数是move()函数,如果在执行完move()函数结束后调用,会在最后一张图片跳转出现问题,无法播放我们放在最后一张图片后面的第一张图片,这样会造成问题4还是存在,并且此时回到第一张的时候index不等于0(注意此时由于加了一张图片imgArr会加一),回到第一张会向后轮播几张后再回到第二张;这时候我们需要用到move()的回调函数,这个实在动画轮播结束后迅速执行,每次转换到下一张时,导航随之变化,比较符合我们的问题,并且不会影响其他值的变化。(这里其实我也觉得很神奇,有点糊涂,讲道理放外面和放里面应该不会有什么区别啊????还得 在研究研究)
              //修改导航点
                    move(imgList,-520*index,10,"left",function () {
                        setA();
                    })     
                },3000)
  1. 解决点击点击导航栏切换图片动画和图片自动轮播动画冲突问题
    点击事件优于自动轮播,所以让自动轮播的计时器等于一个变量,在触发超链接的点击事件,先关闭计时器,然后在移动到相应的图片后在调用auto函数,图片继续自动轮播。
                   llA[i].onclick = function () {
                    clearInterval(timer);
                    index = this.num;
                    //切换图片
                    //第一张 0 0 第二张 1 -520
                    //静态改变图片
                    // imgList.style.left = index * -520 +"px"
                    //加上计时器
                    move(imgList, -520 * index, 10, "left",function () {
                        //动画执行完毕执行自动切换动画
                        auto();
                    });

所有代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        #outer{
            background-color: aquamarine;
            height: 332px;
            margin: 50px auto;
            overflow: hidden;
            position: relative;
            width: 520px;
            padding: 10px 0px;
        }
        #imgList{
            /*width写死了不好*/
            /*width: 2500px;*/
            /*去除项目符号*/
            list-style: none;
            position: absolute;
            /*每向左移动530,到下面一张图*/
        }
        #imgList li{
            float: left;
            margin: 0 10px;
        }
        #navDiv{
            position: absolute;
            bottom: 5px;
            /*left可以利用js设定*/
            /*left=(outerWidth-navDivWidth)/2*/
        }
        #navDiv a{
            float: left;
            width: 10px;
            height: 10px;
            background-color: cadetblue;
            margin-left:5px;
            opacity: 0.7;
            /*兼容IE8*/
            filter: alpha(opacity=70);
        }
        #navDiv a:hover{
            background-color: yellow;
        }
    </style>
    <script type="text/javascript">
        window.onload = function () {

            //设置ul宽度
            var imgList = document.getElementById("imgList");
            var imgArr = document.getElementsByTagName("img");
            // 图片长度加上margin的长度
            imgList.style.width = 530 * imgArr.length + "px";

            //设置下面导航小点的位置
            // 父级元素div的长度减去小点的长度
            var outer = document.getElementById("outer");
            var navDir = document.getElementById("navDiv");
            navDir.style.left = (outer.offsetWidth - navDir.offsetWidth) / 2 + "px";

            // 默认初始索引为0
            var index = 0;
            var allA = document.getElementsByTagName("a");
            allA[index].style.backgroundColor = "yellow";

            //点击不同的超链接,切换到不同的图片
            for (var i = 0; i < allA.length; i++) {
                //为每一个超链接添加num属性
                allA[i].num = i;
                allA[i].onclick = function () {
                    //关闭自动播放的计时器
                    clearInterval(timer);
                    index = this.num;
                    //切换图片
                    //第一张 0 0 第二张 1 -520
                    //静态改变图片
                    // imgList.style.left = index * -520 +"px"
                    //加上计时器
                    move(imgList, -520 * index, 10, "left",function () {
                        //动画执行完毕执行自动切换动画
                        auto();
                    });
                    //修改超链接
                    // this.style.backgroundColor = "yellow";
                    setA();
                }
            }

            //创建方法使得点击的超链接变色其他的不变
            function setA() {
                //判断索引是否为最后一张图片
                if (index >= imgArr.length -1){
                    index = 0;
                    //此时显示最后一张但是和第一张一样
                    imgList.style.left = 0;
                }
                for (var i = 0; i < allA.length; i++) {
                    // 将所有的遍历背景颜色设置为本色

                    // 这样写会使得hover失效,内联样式会覆盖样式表的样式
                    // allA[i].style.backgroundColor = "cadetblue";
                    // 写成空串就不会覆盖
                    allA[i].style.backgroundColor = ""
                }
                // 将选中的超链接变色
                allA[index].style.backgroundColor = "yellow";

            }

            // 获取当前元素的位置
            function getstyle(obj, name) {
                if (window.getComputedStyle) {
                    return getComputedStyle(obj, null)[name];
                } else {
                    return obj.currentScript[name];
                }
            }
            //图片自动切换
            var timer;
            function auto() {
                //开启计时器
                timer = setInterval(function () {
                    //索引自增
                    index++;
                    //判断index的值不能超过最大值
                    if (index == imgArr.length){
                        index = 0;
                    }
                    //修改导航点

                    move(imgList,-520*index,10,"left",function () {
                        setA();
                    })

                },3000)
            }
            auto()
            // 点击链接切换图片
            //   obj:移动元素
            //   target:移动范围目标位置
            //   speed:移动速度(正负)
            //   direction:移动方向
            //   callback:回调函数,动画执行完毕后执行
            function move(obj, target, speed, direction,callback) {
                clearInterval(obj.timer);
                var current = parseInt(getstyle(obj, direction));
                if (current > target) {
                    speed = -speed;
                }
                obj.timer = setInterval(function () {
                    var oldValue = parseInt(getstyle(obj, direction));
                    var newValue = oldValue + speed;
                    if ((speed < 0 && newValue < target) || (speed > 0 && newValue > target)) {
                        newValue = target;
                    }
                    obj.style[direction] = newValue + "px";
                    if (newValue == target) {
                        clearInterval(obj.timer);
                        callback();
                    }
                }, 30);
            }
        }


    </script>
</head>
<body>
<div>
    <div id="outer">
        <ul id="imgList">
            <li>
                <img src="img/1.jpg">
            </li>
            <li>
                <img src="img/2.jpg">
            </li>
            <li>
                <img src="img/3.jpg">
            </li>
            <li>
                <img src="img/4.jpeg">
            </li>
            <li>
                <img src="img/1.jpg">
            </li>
        </ul>
        <div id="navDiv">
            <a href="javascript:;"></a>
            <a href="javascript:;"></a>
            <a href="javascript:;"></a>
            <a href="javascript:;"></a>
        </div>
    </div>
</div>
</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值