纯JS实现轮播图

写在前面 

是的,这个轮播图我看了一天的时间,网上找说明,外加请教别人,自己动手试着写写,昨天看了一下午,夜里又简单想了一下整个流程。终于今天上午开始动手写,磕磕绊绊,跌跌撞撞,完整的轮播让我给实现了。

总的来说,算是完成了,为啥要说算是呢,因为自己在独立地写的过程中还是会出现一些问题,就会看别人怎么写的,怎么实现的,再去对比一下自己的思路。遇到问题,思考问题,再到解决问题,是个需要不断重复的过程,只有这样,才会让自己熟练,时间长了,再遇到问题知道如何解决,从哪些地方去检查。

emmmmmmm,简单的学习心得分享完毕,开始撸思路,撸代码吧。

轮播图

轮播图功能需求:

 1. 鼠标经过/离开轮播图时  左右按钮的显示/隐藏

 2. 点击圆点时,圆度变为当前状态;图片切换

 3. 左右按钮点击时,轮播图片

 4. 图片轮播时 下方的圆点也跟着切换

 5. 鼠标放上焦点图时 图片停止自动轮播  ; 鼠标离开时 图片自动轮播

 需要注意的是,页面一开始图片就是轮播着的

优化的地方:

1. 增加节流阀:

当连续点击按钮时,一张图片没有轮播完就会出现下一张。增加的节流阀的目的就是解决上面所叙述的问题。一般节流阀就是两种操作,关闭节流阀(锁函数),打开节流阀(开函数)。

2. 提取代码相同的部分,单独作为一个函数,进行调用。还有就是把一些简单的if语句的判断可以使用三元表达式来代替

无缝轮播的思想

无缝轮播的布局:把放轮播图的ul中的第一个孩子li,复制一份放到ul的最后。

轮播具体实现的过程:正常的话,用户点击按钮进行图片的轮播,当用户看到最后一张图片(其实是我们布局中的倒数第二张)时,点击右侧按钮的时候,用户看到的是第一张图片,其本质是用户看到了我们布局中的最后一张,因为这一张图是我们复制的第一张图,与此同时,我们悄悄的把ul瞬间回到原位置(left = 0),制造假象,让用户以为是第一张图片,其实是我们布局中的最后一张。当用户再点击时,因为此时ul已经瞬间移回到原来的位置,再点击向右轮播的按钮,ul就按照正常的轮播到第二张图片。这样就实现了无缝轮播。

这是轮播图中比较重要的一个思想。思路解决了 ,咱们就看代码吧。

代码里面有很详细的解释,可以认真看看的。

JS部分

// 轮播图的需求:
// 1. 鼠标经过/离开轮播图时  左右按钮的显示/隐藏
// 2. 点击圆点时,圆度变为当前状态;图片切换
// 3. 左右按钮点击时,轮播图片
// 4. 图片轮播时 下方的圆点也跟着切换
// 5. 鼠标放上焦点图时 图片停止自动轮播  ; 鼠标离开时 图片自动轮播
// 需要注意的是,页面一开始图片就是轮播着的
window.addEventListener('load', function () {

    // 1. 鼠标经过轮播图时 按钮的显示和隐藏
    // 获取事件源
    var focus = document.querySelector('.focus');
    var arrowL = document.querySelector('.arrow-l');
    var arrowR = document.querySelector('.arrow-r');
    var ol = document.querySelector('.circle');
    var ul = focus.querySelector('ul');
    var focusWidth = focus.offsetWidth;
    focus.addEventListener('mouseenter', function () {
        arrowL.style.display = 'block';
        arrowR.style.display = 'block';
        clearInterval(carousel);
        carousel = null;
    })
    focus.addEventListener('mouseleave', function () {
        arrowL.style.display = 'none';
        arrowR.style.display = 'none';
        // 鼠标离开 自动轮播
        carousel = setInterval(function () {
            arrowR.click();
        }, 3000)
    })
    // 2.点击圆点部分
    // 圆点的个数应该是与图片的个数是一致的,所以 应该根据ul中的li的个数动态创建圆点的个数
    // js需要写的具有一定的动态性 改变结构 时 js可以动态生成
    for (var i = 0; i < ul.children.length; i++) {
        // (1)创建圆点 
        var li = document.createElement('li');
        // (2)添加到ol中
        ol.appendChild(li);
        // 设置一个变量 用来记录当前圆点的索引号 后面与图片位置对应显示
        li.setAttribute('index', i);
        // (3).点击圆点的事件效果 应该在创建之后就绑定事件
        li.addEventListener('click', function () {
            // (4).被点击的圆点 变成当前状态
            // 干掉所有人 ol.children.length所有小圆点的个数
            for (var i = 0; i < ol.children.length; i++) {
                ol.children[i].className = '';
            }
            // 留下我自己 当前点击的圆点
            this.className = 'current';

            // (5). 点击时图片轮播
            // 获得当前圆点的索引号
            var currentIndex = this.getAttribute('index');
            // 轮播到哪个li 把当前图片对应的圆点的索引号 给点击的次数
            // 是保持圆点 按钮点击次数 图片对应一致
            clickCount = currentIndex;
            circleMove = currentIndex;

            // ul移动的距离  圆点索引号*焦点图的宽度
            animate(ul, -currentIndex * focusWidth);

        })
    }

    // 默认设置第一个圆点为当前
    ol.children[0].className = 'current';
    // 无缝轮播:把ul中的图片复制一份到ul的最后。当用户点击到最后一张,就是我们的倒数第二张
    // 用户再点击时 看到的是第一张的图片 其实是我们复制了第一张到ul的最后,所以用户看到的实际上是我们复制的那一张图
    // 这时当用户再点击时  我们迅速把ul移回原位left=0,从头开始 再按照正常的轮播到第二张


    // 克隆节点在创建小圆点的后面 因为克隆出来的节点不需要小圆点
    // 复制ul第一个li放到最后 ul.children[0].cloneNode(true)深拷贝
    var firstImg = ul.children[0].cloneNode(true);
    ul.appendChild(firstImg);
    // 点击按钮事件
    // 点击右侧按钮 图片向左轮播 点击一次 图片(ul)移动一个图片的距离
    // ul移动的距离 = 点击次数*焦点图的宽度  与上面点小圆点的效果类似
    // 设置一个变量记录 点击的次数  点击一次图片滚动一次
    var clickCount = 0;
    // 记录圆点的位置 控制圆点的播放
    var circleMove = 0;
    // 节流阈值:为了防止点击过快图片没有轮播完就结束的情况
    var flag = true;
    // 3.右侧按钮点击
    arrowR.addEventListener('click', function () {
        if (flag) {
            // 先锁住函数 当动画执行完毕之后 再解锁
            flag = false; // 关闭节流阀
            // (1) 当ul走到最后 我们复制的那一张图片时:ul的left = 0;迅速复原ul
            if (clickCount == ul.children.length - 1) {
                ul.style.left = 0;
                clickCount = 0; // 点击置0
            }

            clickCount++;
            animate(ul, -clickCount * focusWidth, function () {
                flag = true; // 打开节流阀
            });

            // (2) 图片轮播时 圆点也在变化
            circleMove++;
            // 当圆点到最后一个4 也就是图片轮播到我们复制的哪一个图片时  圆点从头开始
            if (circleMove == ol.children.length) {
                circleMove = 0
            }
            // circleMove == ol.children.length - 1 ? 0 : circleMove;
            // 调用函数 排他思想
            circleVisible();
        }


    })

    // 4.左侧按钮点击
    arrowL.addEventListener('click', function () {
        if (flag) {
            flag = false;
            // (1) 当ul是第一张图片时 点击时应轮播到倒数第二张 
            if (clickCount == 0) {
                ul.style.left = -clickCount * focusWidth + 'px';
                clickCount = ul.children.length - 1; // 点击数也回到图片对应的点击数
            }
            clickCount--;
            animate(ul, -clickCount * focusWidth, function () {
                flag = true;
            });

            // (2) 图片轮播时 圆点也在变化
            circleMove--;
            // 点击时 如果 circleMove < 0 说明是第一张图片 小圆点要从第4个开始 (索引号3)
            if (circleMove < 0) {
                circleMove = ol.children.length - 1
            }
            // circleMove < 0 ? ol.children.length - 1 : circleMove;
            // 调用函数 排他思想
            circleVisible();
        }
    })

    // 5.鼠标经过时  设置定时器 自动轮播图片
    // 自动轮播的效果 与点击右侧按钮的效果一样
    // 即可以使用手动调取 右侧按钮点击事件
    var carousel = setInterval(function autoCarousel() {
        arrowR.click();
    }, 3000)

    // 排他
    function circleVisible() {
        // 干掉所有人
        for (var i = 0; i < ol.children.length; i++) {
            ol.children[i].className = '';
        }
        // 留下自己
        ol.children[circleMove].className = 'current';
    }

})

 

结构部分

这里有需要注意的一点,轮播图用到了之前封装的动画函数,需要引入动画的js文件,动画的js文件要在页面的js文件之前引入,因为动画js是依赖于页面的js文件的。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./css/lb.css">
    <!-- 依赖于lb.js 因为只有在有js文件时才会引入动画函数 所以要在前面引入 -->
    <script src="./js/animate.js"></script>
    <script src="./js/lb.js"></script>
</head>

<body>
    <div class="w">
        <div class="focus">
            <!-- 左侧按钮 -->
            <a href="javascript:;" class="arrow-l">
                
            </a>
            <!-- 右侧按钮 -->
            <a href="javascript:;" class="arrow-r"></a>
            <!-- 核心的滚动区域 -->
            <ul>
                <li>
                    <a href="#"><img src="upload/focus.jpg" alt=""></a>
                </li>
                <li>
                    <a href="#"><img src="upload/focus1.jpg" alt=""></a>
                </li>
                <li>
                    <a href="#"><img src="upload/focus2.jpg" alt=""></a>
                </li>
                <!-- 注意这是第一张图片复制过来的  -->
                <li>
                    <a href="#"><img src="upload/focus3.jpg" alt=""></a>
                </li>
            </ul>
            <!-- 小圆圈 -->
            <ol class="circle">

            </ol>
        </div>
    </div>

</body>

</html>

 

 

ok,轮播图克服掉了。

春意盎然,我的寒假还在继续。。。。。。

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
实现 HTML 和 CSS 的轮播图可以用到 `input:checked` 和 `label` 标签的特性。以下是一个简单的示例: ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>CSS轮播图</title> <style> /* 隐藏所有轮播图 */ .carousel-inner > input { display: none; } /* 设置图片宽高和定位 */ .carousel-inner > img { width: 100%; height: 100%; position: absolute; top: 0; left: 0; opacity: 0; /* 设置透明度为0,隐藏图片 */ transition: opacity 1s ease-in-out; /* 设置渐变效果 */ } /* 显示当前选中的图片 */ .carousel-inner > input:checked + img { opacity: 1; } /* 设置圆点样式 */ .carousel-indicators { position: absolute; bottom: 10px; left: 50%; transform: translateX(-50%); display: flex; justify-content: center; align-items: center; } /* 设置圆点样式 */ .carousel-indicators > label { width: 10px; height: 10px; border-radius: 50%; background-color: #999; margin: 0 5px; cursor: pointer; transition: background-color 0.5s ease-in-out; } /* 设置选中圆点样式 */ .carousel-indicators > input:checked + label { background-color: #333; } /* 隐藏input元素 */ .carousel-indicators > input { display: none; } </style> </head> <body> <div class="carousel-inner"> <input type="radio" id="slide-1" name="slides" checked> <img src="https://picsum.photos/id/1019/800/400" alt="Slide 1"> <input type="radio" id="slide-2" name="slides"> <img src="https://picsum.photos/id/1020/800/400" alt="Slide 2"> <input type="radio" id="slide-3" name="slides"> <img src="https://picsum.photos/id/1021/800/400" alt="Slide 3"> <div class="carousel-indicators"> <input type="radio" id="slide-1-input" name="slide-indicators" checked> <label for="slide-1-input"></label> <input type="radio" id="slide-2-input" name="slide-indicators"> <label for="slide-2-input"></label> <input type="radio" id="slide-3-input" name="slide-indicators"> <label for="slide-3-input"></label> </div> </div> </body> </html> ``` 在这个示例中,轮播图中有3张图片,每张图片都有一个对应的 input 元素,并且这些 input 元素都有相同的 `name` 属性,以便它们可以被分组,只有一个 input 被选中。圆点也是用类似的方式实现的:每个圆点都是一个 `label` 元素,它用于选择相应的 input 元素。 当 `input:checked` 时,当前图片的 `opacity` 属性被设置为 `1`,这样就可以显示当前选中的图片。 同样,当 `input:checked` 时,当前圆点的 `background-color` 属性被设置为 `#333`,这样就可以显示当前选中状态的圆点。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值