JavaScript实现轮播图


一 元素内容分析

1.一个播放窗口
2.方向键
3.要播放的图片
4.随图片播放的小圆圈

二 功能分析

1.方向键根据窗口高度自动居中,左右间隔固定
2.根据图片数量自动创建小圆圈
3.点击小圆圈图片随之改变,小圆圈必须与图片对应
4.点击方向键,图片也随之改变
5.鼠标移入窗口,则显示方向键,同时播放停止
6.鼠标移除窗口,则方向键隐藏,播放恢复
7.图片自动播放

三 具体实现

1.添加页面元素

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>轮播图</title>
</head>
<body>
    <div id="focus">
        <ul>
            <li><img src="img/703.jpg" alt=""></li><li><img src="img/704.jpg" alt=""></li><li><img src="img/705.jpg" alt=""></li><li><img src="img/706.jpg" alt=""></li>
        </ul>
        <ol></ol>
        <!-- 方向键标签 -->
        <a class="direction left" href="javascript:;">&lt;</a>
        <a class="direction right" href="javascript:;">&gt;</a>
    </div>
</body>
</html>
  • 注意
    如果li元素不写在同一行即:

    <li><img src="img/703.jpg" alt=""></li>
    <li><img src="img/704.jpg" alt=""></li>
    <li><img src="img/705.jpg" alt=""></li>
    <li><img src="img/706.jpg" alt=""></li>
    

    这样写的话,当li的display属性改为inline-block时,图片与图片之间会有孔隙,如果不希望出现空隙,可以将li元素写在同一行,或者float改为left(建议改float)

2.调整css样式

  <style>
    * {
        margin: 0;
        padding: 0;
    }

    #focus {
        width: 500px;
        height: 300px;
        margin: 50px auto;
        position: relative;
        border: 0px solid red;
        overflow: hidden;
    }

    ul {
        list-style: none;
        /* 此处为六张图片的总长度(通过js代码将第一张图片和最后一张复制了一份) */
        width: 3000px;
        height: 300px;
        position: absolute;
        left: -500px;
        /* 过渡效果:使宽度缓慢变化(也可以在代码中添加) */
        /* transition: all .3s; */
        /* user agent stylesheet */
        margin-block-start: 0em;
        margin-block-end: 0em;
        padding-inline-start: 0px;
    }

    ul li {
        width: 500px;
        height: 300px;
        /* 如果设置为inline-block/inline,则图片之间会有孔隙(2.5px),可将li元素写在同一行消除*/
        /* display: inline-block; */
        float: left;
        text-align: left;
    }

    ul li img {
        width: 500px;
        height: 300px;
    }

    ol {
        position: absolute;
        bottom: 10px;
    }

    ol li {
        display: inline-block;
        list-style: none;
        width: 10px;
        height: 10px;
        border-radius: 50%;
        outline: 1px solid #666;
        background-color: white;
        margin: 0 5px;
    }

    #focus ol li.current {
        background-color: red;
    }

    #focus .direction {
        background-color: #555;
        font-size: 14px;
        text-align: center;
        color: #eee;
        width: 4%;
        height: 10%;
        /* line-height设置为字体的两倍可实现垂直居中 */
        line-height: 28px;
        text-decoration: none;
        position: absolute;
        opacity: 0.3;
        display: none;
        cursor: pointer;
    }

    #focus .left {
        left: 5px;
    }

    #focus .right {
        right: 5px;
    }
  </style>

3.功能实现

<script>
    window.addEventListener("load", function () {
        // 获取元素对象
        var focus = document.querySelector("#focus");
        var ul = focus.children[0];
        var ol = focus.children[1];
        // 获取方向键元素对象
        var direction = foucs.querySelectorAll(".direction");

        // 获得focus的宽度和高度
        var focus_width = focus.offsetWidth;
        var focus_height = focus.offsetHeight;

        // 创建图片的索引
        var img_index = 0;

        // 设置节流阀开关
        // 如果不设置节流阀,当短时间内多次点击方向键时,图片滚动还没结束就会开启下一次滚动
        var flag = true;

        // (1)自动设置方向键的top
        direction[0].style.top = (focus_height - focus_height / 10) / 2 + "px";
        direction[1].style.top = direction[0].style.top;

        // (2)自动生成小圆圈的个数和居中
        for (var i = 0; i < ul.children.length; i++) {
            var li = document.createElement("li");
            // 添加小圆圈的index属性,并赋值为i;
            li.index = i;
            ol.appendChild(li);
        };
        ol.children[0].classList.add("current");        // 将current样式类赋给第一个小圆圈
        ol.style.left = (focus_width - ol.offsetWidth) / 2 + "px";      // 居中

        // (3)克隆左右两边的图片并添加到ul中(为实现无缝滚动)
        var newimg_1 = ul.children[0].cloneNode(true);
        var newimg_4 = ul.children[3].cloneNode(true);
        ul.appendChild(newimg_1);                   // 加入到ul的最后面
        ul.insertBefore(newimg_4, ul.children[0]);  // 在ul的最前方插入

        // (4)鼠标经过focus显示方向键
        focus.addEventListener("mouseenter", function () {
            direction[0].style.display = "block";
            direction[1].style.display = "block";
            // 鼠标移入移除定时器
            clearInterval(timer);
        })

        // (5)鼠标离开隐藏方向键
        focus.addEventListener("mouseleave", function () {
            direction[0].style.display = "none";
            direction[1].style.display = "none";
            // 鼠标移除重新添加定时器
            timer = setInterval(function(){
                direction[1].click();
            }, 2000);
        })

        // (6)点击小圆圈实现小圆圈的样式变化,并让图片滚动切换
        ol.addEventListener("click", function (e) {
            // console.log(e.currentTarget,e.target.tagName);
            // importerror --> if(e.target.tagName == "li"||"LI")  不生效,但不会报错
            if (e.target.tagName == "LI" || e.target.tagName == "li") {
                // 将圆圈索引赋值给图片索引
                img_index = e.target.index;
                console.log("图片索引"+img_index, "圆圈索引"+e.target.index);
                // // 把ol里带有current类名的li元素选出来,去掉类名 remove
                // ol.querySelector(".current").classList.remove("current");
                // // 让当前的索引号的li元素加上current add
                // ol.children[img_index].classList.add("current");
                // // 加上过渡效果
                // ul.style.transition = 'all .2s';
                // // ul的移动距离 = 小圆圈的索引*图片的宽度 + "px"
                // ul.style.left = -(e.target.index + 1) * focus_width + "px";
                roll(img_index, true);
            }
        })

        // (7)点击方向键实现图片滚动
        direction[0].addEventListener("click", function(){
            if(flag){
                flag = false;   // 节流阀关闭
                img_index = ol.querySelector(".current").index;  // 使小圆圈的索引与图片的索引一致
                img_index--;
                if(img_index < 0) {
                    // 当图片滚动到第一张时,继续向左滚动
                    roll_img(img_index, true)
                    /// 滚动结束后将图片的索引设置为最后一张,此时显示的实际上是通过代码复制的最后一张图片,只是将它放到了第一张图片前面
                    img_index = 3;
                    roll_circul(img_index)

                    ul.addEventListener("transitionend", function(){
                        // 滚动结束后,关闭过渡效果显示
                        ul.style.transition = "none";
                        // 同时将ul的left值设置到刚好显示最后一张图片的位置上
                        // 因为实际不止四张图片,所以img_index要加1,这样才能刚好显示第四张图片
                        ul.style.left = -(img_index + 1) * focus_width + "px";
                    });
                } else {
                    roll(img_index, true);
                }
                ul.addEventListener("transitionend", function(){
                        // 动画结束则打开节流阀
                        flag = true;
                });
            }
        })

        direction[1].addEventListener("click", function(){
            if(flag){
                flag = false;   // 节流阀关闭
                img_index = ol.querySelector(".current").index;  // 使小圆圈的索引与图片的索引一致
                img_index++;
                if(img_index > 3) {
                    roll_img(img_index, true)
                    img_index = 0;
                    roll_circul(img_index)

                    ul.addEventListener("transitionend", function(){   
                        ul.style.transition = "none";
                        ul.style.left = -(img_index + 1) * focus_width + "px";
                    });
                } else {
                    roll(img_index, true);
                }
                ul.addEventListener("transitionend", function(){
                        // 动画结束则打开节流阀
                        flag = true;
                });
            } 
        })

        // (8)实现自动轮播
        var timer = setInterval(function(){
            // 自动播放可通过调用右方向键的点击事件实现
            direction[1].click();
        }, 2000)

        // 功能函数(emmmm封装的不是很好)
        function roll (index, bool) {
            // 把ol里带有current类名的li元素选出来,去掉类名 remove
            ol.querySelector(".current").classList.remove("current");
            // 让当前的索引号的li元素加上current add
            ol.children[index].classList.add("current");
            if (bool) {
                // 加上过渡效果
                ul.style.transition = 'all .5s';
            } else {
                ul.style.transition = "none";
            }
            // ul的移动距离 = 小圆圈的索引*图片的宽度 + "px"
            ul.style.left = -(index + 1) * focus_width + "px";
        }

        function roll_img(index, bool){
            if (bool) {
                // 加上过渡效果
                ul.style.transition = 'all .5s';
            } else {
                ul.style.transition = "none";
            }
            // ul的移动距离 = 小圆圈的索引*图片的宽度 + "px"
            ul.style.left = -(index + 1) * focus_width + "px";
        }

        function roll_circul (index) {
            // 把ol里带有current类名的li元素选出来,去掉类名
            ol.querySelector(".current").classList.remove("current");
            // 让当前的索引号的li元素加上current
            ol.children[index].classList.add("current");
        }
    })         
</script>

原创文章,作者:,如若转载,请注明出处:https://blog.ytso.com/272723.html

(0)
上一篇 2022年7月9日
下一篇 2022年7月9日

相关推荐

发表回复

登录后才能评论