您好!欢迎访问家园网-www.jy.wang!

家园网

下面的轮播图是如何实现的?要逐行讲解清楚原理

网络 作者:本站 点击:

下面的轮播图是如何实现的?要逐行讲解清楚原理

html代码:

    <div class="mr-slider mr-slider-default scoll" data-mr-flexslider id="demo-slider-0">
        <div id="box">
            <ul id="imagesUI" class="list">
                <li class="current" style="opacity: 1;"><img src="images/ad1.png"></li>
                <li style="opacity: 0;"><img src="images/ad2.png" ></li>
                <li style="opacity: 0;"><img src="images/ad3.png" ></li>
                <li style="opacity: 0;"><img src="images/ad4.png" ></li>
            </ul>
            <ul id="btnUI" class="count">
                <li class="current">1</li>
                <li class="">2</li>
                <li class="">3</li>
                <li class="">4</li>
            </ul>
        </div>
    </div>
    <div class="clear"></div>


js代码:

<script>
    //alert(window.innerWidth);
    var box=document.getElementById('box');
    var imagesUI=document.getElementById('imagesUI');
    var btnUI=document.getElementById('btnUI');
    var imgs=imagesUI.getElementsByTagName('li');
    var btn=btnUI.getElementsByTagName('li');
    var i=index=0; //中间量,统一声明;
    var play=null;
    console.log(box,imgs,imgs,btn);//获取正确

    autoPlay();//马上调用,我试过用window.onload调用这个方法,但是调用之后影响到了其他方法,使用autoPlay所以只能这样调用了

    //div的鼠标移入移出事件
    box.onmouseover=function(){
        clearInterval(play);
    };
    box.onmouseout=function(){
        autoPlay();
    };
    //自动轮播方法
    function autoPlay(){
        play=setInterval(function(){ //定时器处理
            index++;
            index>=imgs.length&&(index=0);
            show(index);
        },3000)
    }

    //图片切换方法
    function show(a){
        for(i=0;i<btn.length;i++ ){
            btn[i].className='';    //显示当前设置按钮。
            btn[a].className='current';
        }
        for(i=0;i<imgs.length;i++){ //把图片的效果设置和按钮相同
            imgs[i].style.opacity=0;
            imgs[a].style.opacity=1;
        }
    }
    //切换按钮功能
    for(i=0;i<btn.length;i++){
        btn[i].index=i;
        btn[i].onmouseover=function(){
            show(this.index);
            clearInterval(play);
        }
    }

</script>

轮播图实现原理逐行详解

这是一个典型的淡入淡出轮播图,通过改变图片的透明度(opacity)来实现图片切换,同时配合底部按钮的高亮显示。


一、HTML 结构分析

html

<div class="mr-slider mr-slider-default scoll" data-mr-flexslider id="demo-slider-0">
    <div id="box">
        <!-- 图片列表 -->
        <ul id="imagesUI" class="list">
            <li class="current" style="opacity: 1;"><img src="images/ad1.png"></li>
            <li style="opacity: 0;"><img src="images/ad2.png" ></li>
            <li style="opacity: 0;"><img src="images/ad3.png" ></li>
            <li style="opacity: 0;"><img src="images/ad4.png" ></li>
        </ul>
        
        <!-- 按钮列表(指示器) -->
        <ul id="btnUI" class="count">
            <li class="current">1</li>
            <li class="">2</li>
            <li class="">3</li>
            <li class="">4</li>
        </ul>
    </div></div>

关键点

元素作用初始状态
#box轮播图容器,用于监听鼠标事件-
#imagesUI .list li图片项,共4张第1张透明1(可见),其余透明0(不可见)
#btnUI .count li按钮指示器第1个高亮(current),其余普通

透明度原理opacity: 1 完全可见,opacity: 0 完全透明(不可见)。通过改变图片项的 opacity 实现淡入淡出切换。


二、JS 代码逐行详解

1、变量声明与元素获取

javascript

var box = document.getElementById('box');var imagesUI = document.getElementById('imagesUI');var btnUI = document.getElementById('btnUI');

  • 获取三个核心容器的 DOM 元素

  • box:轮播图容器(用于鼠标事件)

  • imagesUI:图片列表容器

  • btnUI:按钮列表容器


javascript

var imgs = imagesUI.getElementsByTagName('li');var btn = btnUI.getElementsByTagName('li');

  • imgs:获取所有图片项(<li>),共 4 个

  • btn:获取所有按钮项(<li>),共 4 个


javascript

var i = index = 0;  // 中间量,统一声明var play = null;

  • i:循环计数器,用于 for 循环

  • index:当前显示的图片索引(0、1、2、3)

  • play:定时器变量,用于存储 setInterval 的返回值


javascript

console.log(box, imgs, btn);  // 获取正确

  • 控制台输出,验证元素是否获取成功


2、启动自动轮播

javascript

autoPlay();  // 马上调用

  • 立即执行 autoPlay() 函数,启动定时器

  • 注释说明:尝试过用 window.onload 但会影响其他方法,所以直接调用


3、鼠标移入移出事件

javascript

box.onmouseover = function() {
    clearInterval(play);};

  • 鼠标移入轮播图容器时,清除定时器

  • clearInterval(play):停止自动轮播

  • 目的:用户想要手动操作时,暂停自动切换


javascript

box.onmouseout = function() {
    autoPlay();};

  • 鼠标移出轮播图容器时,重新启动自动轮播

  • 调用 autoPlay() 恢复定时器


4、自动轮播方法

javascript

function autoPlay() {
    play = setInterval(function() {
        index++;
        index >= imgs.length && (index = 0);
        show(index);
    }, 3000)}

逐行解释

代码含义
play = setInterval(...)启动定时器,每 3 秒执行一次,返回值存入 play
index++索引加 1(切换到下一张)
index >= imgs.length && (index = 0)如果索引达到最后一张(4),则回到 0(第一张)
show(index)调用 show 函数,切换到指定索引的图片

示例

  • 第1次:index=0 → 加1后 index=1 → show(1) → 显示第2张

  • 第2次:index=1 → 加1后 index=2 → show(2) → 显示第3张

  • 第3次:index=2 → 加1后 index=3 → show(3) → 显示第4张

  • 第4次:index=3 → 加1后 index=4 → 判断后变为0 → show(0) → 回到第1张


5、图片切换方法

javascript

function show(a) {
    // 1. 按钮样式切换
    for (i = 0; i < btn.length; i++) {
        btn[i].className = '';
        btn[a].className = 'current';
    }
    
    // 2. 图片透明度切换
    for (i = 0; i < imgs.length; i++) {
        imgs[i].style.opacity = 0;
        imgs[a].style.opacity = 1;
    }}

参数 a:要切换到第几张图片(0,1,2,3)

第一步:按钮样式切换

javascript

for (i = 0; i < btn.length; i++) {
    btn[i].className = '';      // 清除所有按钮的 class
    btn[a].className = 'current'; // 给当前按钮添加高亮 class}

  • 注意:这个循环写法有问题!btn[a].className = 'current' 每次循环都执行,效率低且逻辑混乱。

正确写法应该是

javascript

// 先全部清空for (i = 0; i < btn.length; i++) {
    btn[i].className = '';}// 再单独设置当前按钮btn[a].className = 'current';

第二步:图片透明度切换

javascript

for (i = 0; i < imgs.length; i++) {
    imgs[i].style.opacity = 0;  // 所有图片设为透明
    imgs[a].style.opacity = 1;  // 当前图片设为可见}

  • 同样的问题:imgs[a].style.opacity = 1 在循环内重复执行 4 次

正确写法

javascript

for (i = 0; i < imgs.length; i++) {
    imgs[i].style.opacity = 0;}imgs[a].style.opacity = 1;


6、手动点击按钮切换

javascript

for (i = 0; i < btn.length; i++) {
    btn[i].index = i;  // 给每个按钮添加自定义属性 index,记录自己的索引
    btn[i].onmouseover = function() {
        show(this.index);      // 切换到对应图片
        clearInterval(play);   // 停止自动轮播
    }}

逐行解释

代码含义
btn[i].index = i给每个按钮添加一个 index 属性,值为 0、1、2、3
btn[i].onmouseover = function() { ... }绑定鼠标移入事件
show(this.index)调用 show 函数,this.index 就是当前按钮的索引
clearInterval(play)清除定时器,停止自动轮播

为什么需要 btn[i].index = i

  • 如果不设置,在回调函数中无法知道当前按钮是第几个

  • 直接用 i 会变成循环结束后的值(始终为 4),这是 JavaScript 闭包的经典问题


三、完整执行流程图

text

┌─────────────────────────────────────────────────────────────────┐
│                        页面加载                                  │
│                            ↓                                    │
│                    autoPlay() 启动                              │
│                            ↓                                    │
│              setInterval 每 3 秒执行一次                         │
│                            ↓                                    │
│                   index++ → 切换到下一张                         │
│                            ↓                                    │
│                    show(index) 执行                             │
│                            ↓                                    │
│          ┌─────────────────────────────────────┐                │
│          │  1. 清空所有按钮的 class            │                │
│          │  2. 给当前按钮添加 current class     │                │
│          │  3. 所有图片 opacity 设为 0         │                │
│          │  4. 当前图片 opacity 设为 1         │                │
│          └─────────────────────────────────────┘                │
│                            ↓                                    │
│                      图片切换完成                                │
└─────────────────────────────────────────────────────────────────┘

                        同时,用户可交互:

┌─────────────────────────────────────────────────────────────────┐
│                    鼠标移入轮播图                                │
│                            ↓                                    │
│              clearInterval(play) → 停止自动轮播                  │
│                            ↓                                    │
│                      手动点击按钮                                │
│                            ↓                                    │
│                    show(点击的索引) → 切换图片                    │
│                            ↓                                    │
│              clearInterval(play) → 再次停止自动轮播               │
│                            ↓                                    │
│                    鼠标移出轮播图                                │
│                            ↓                                    │
│                    autoPlay() → 重新启动                         │
└─────────────────────────────────────────────────────────────────┘


四、代码存在的问题及改进

问题说明改进
循环中重复赋值show() 函数中在循环内重复设置当前项将当前项设置移到循环外
索引依赖menu[3] 依赖 HTML 格式用 querySelector 代替
全局变量过多i 声明在全局使用 let 局部变量
无防抖快速移入移出可能多次触发添加防抖处理

五、总结

核心功能实现方式
自动轮播setInterval 定时器,每 3 秒 index++ 并调用 show()
图片切换改变图片的 opacity 属性(0 透明 / 1 可见)
按钮高亮改变按钮的 className(添加/移除 current
鼠标交互mouseover 暂停,mouseout 恢复
手动切换点击按钮时调用 show() 并清除定时器

一句话总结:轮播图通过定时器自动递增索引,改变图片的透明度实现淡入淡出切换,同时更新底部按钮的高亮状态;鼠标移入时暂停自动播放,移出时恢复,点击按钮可直接跳转到对应图片


标签: