0

0

如何使用原生JavaScript实现轮播图?代码详解

php是最好的语言

php是最好的语言

发布时间:2018-08-07 10:58:27

|

3245人浏览过

|

来源于php中文网

原创

实现原理

1.png

通过自定义的animate函数来改变元素的left值让图片呈现左右滚动的效果

HTML:




    
    
    


    

  • 如何使用原生JavaScript实现轮播图?代码详解
  • 如何使用原生JavaScript实现轮播图?代码详解
  • 如何使用原生JavaScript实现轮播图?代码详解
  • 如何使用原生JavaScript实现轮播图?代码详解
  • 如何使用原生JavaScript实现轮播图?代码详解

    CSS:

    body, p, p,
    h1, h2, h3, h4, h5, h6,
    dl, dt, dd, ul, ol, li,
    table, caption, th, td,
    form, fieldset, input, textarea, select,
    pre, address, blockquote,
    embed, object {
        margin: 0px;
        padding: 0px;
    }
    
    ul, ol {
        list-style:none;
    }
    
    img {
        vertical-align: top;
    }
    
    .scroll {
        width: 950px;
        height: 438px;
        margin: auto;
        overflow: hidden;
        position: relative;
    }
    
    .box {
        width: 950px;
        height: 438px;
        overflow: hidden;
        position: relative;
    }
    
    .box ul{
        width: 700%;
        position: absolute;
        left: 0;
        top: 0;
        padding:0px;
        margin:0px;
    }
    
    .box ul li{
        float: left;
    }
    
    .scroll ol {
        position: absolute;
        right: 365px;
        bottom: 5px;
    }
    
    .scroll ol li {
        float: left;
        width: 20px;
        height: 20px;
        border-radius: 50%;
        background: #000;
        margin-left: 10px;
        cursor: pointer;
        opacity: 0.5;
    }
    
    .scroll ol li.current {
        background-color: #000099;
        opacity: 0.8;
    }
    
    #last {
        position: absolute;
        bottom: 179px;
        width: 80px;
        height: 80px;
        cursor: pointer;
    }
    
    #next {
        position: absolute;
        bottom: 179px;
        right: 0px;
        width: 80px;
        height: 80px;
        cursor: pointer;
    }

    1.png

    展示效果如上图 

    立即学习Java免费学习笔记(深入)”;

    接下来讲解js代码 ,先获取html中的元素

    var scroll = document.getElementById("scroll");
    var ul = document.getElementById("ul");
    var ulLis = ul.children;
    var liWidth = ul.children[0].offsetWidth;


    再此之前,我们要明白,小圆点并不是写死的,它是根据ul li中的图片张数来决定的 。

    var ol = document.getElementById("olnavi");
    for (var i = 0; i < ulLis.length - 2; i++) {
        var li = document.createElement("li");
        li.id = (i + 1);  //id用于后面为li添加事件
        ol.appendChild(li);
        
    }
    ol.children[0].className = "current" //将第一个小圆点设置为触发状态

    要实现无缝滚动 就需要多两张图片才行 ,即克隆第一张图片,放到最后一张的后面,克隆最后一张,放到第一张的前面。

    var num = ulLis.length - 1;
    ul.appendChild(ul.children[0].cloneNode(true));
    ul.insertBefore(ul.children[num].cloneNode(true), ul.firstChild);

    接下来为左右箭头添加事件,鼠标放到箭头上会变色

    var last = document.getElementById("last");
    last.style.background = "url(images/last-control.png)";
    
    last.addEventListener("mouseenter", function () {
        last.style.background = "url(images/newlast-control.png)";
    }, false);
    
    last.addEventListener("mouseleave", function () {
        last.style.background = "url(images/last-control.png)";
    }, false);
    
    var next = document.getElementById("next");
    next.style.background = "url(images/next-control.png)";
    
    next.addEventListener("mouseenter", function () {
        next.style.background = "url(images/newnext-control.png)";
    }, false);
    
    next.addEventListener("mouseleave", function () {
        next.style.background = "url(images/next-control.png)";
    }, false);

    我们接着用js做动画 动画部分包括: 
    1.鼠标点击第几个小圆点,就要展示第几张图片,并且小圆点的颜色也发生变化.
    2. 鼠标点击左右箭头,图片向左右移动一张
    3.图片自动轮播,(这需要一个定时器)
    4.鼠标放在图片上,图片停止自动播放(这需要清除定时器)
    5.鼠标离开图片,图片继续自动轮播 (重新开始定时器) 
    这里我们封装了一个animate()动画函数

    HIX.AI
    HIX.AI

    HIX.AI是一个多功能的一体化AI写作助手,集成了120多种AI写作工具,支持50多种语言,能够满足各种写作需求。

    下载
    function animate(obj, target) {  //obj为需要移动的元素,在本文中为ul,target为需要移动到的位置
        var speed = obj.offsetLeft < target ? 10 : -10;  //判断速度向左还是向右
        obj.timer = setInterval(function () {  //计时器每隔一定时间移动一次
            var result = target - obj.offsetLeft;  //剩余需要移动的距离
            obj.style.left = obj.offsetLeft + speed + "px";  //改变元素的left来实现移动          
            if (Math.abs(result) <= Math.abs(speed)) {  //当需要移动的距离小于速度时
                clearInterval(obj.timer);   //清除计时器
                obj.style.left = target + "px";  //直接移动到需要移动的位置
                flag = true;  //将flag置为true,使点击事件能再次触发
            }
        }, 1);
    }

    接下来把动画函数赋给左右箭头

    var flag = true;  //用于判断上一个事件是否执行完毕,如果没有执行完毕禁止再次触发事件
    var index = 1;  //是第几个小圆点
    var lastclick = function () {
        if (flag) {
            flag = false;  //进入事件将flag置为false
            console.log(flag);
            if (index === 1) {  //判断是否为第一张
                index = 6;
                ul.style.left = "-5700px";  //当移动到第一张时,再向右移前会替换到最后一张后面的第一张,然后再向右移动。
                animate(ul, ul.offsetLeft + liWidth); //动画函数一次向有移动一个图片长度的距离
            }
            else {
                animate(ul, ul.offsetLeft + liWidth);
            }
            index -= 1; //移动小圆点计数器
            btnShow(index);  //给新的小圆点高亮,取消上一个小圆点的高亮
        }
    }
    last.addEventListener("click", lastclick, false);  //将函数赋给点击事件
    
    var nextclick = function () {  //向左移与向右移类似
        if (flag) {
            flag = false;
            if (index === 5) {
                index = 0;
                ul.style.left = "0px";
                animate(ul, ul.offsetLeft - liWidth);
            }
            else {
                animate(ul, ul.offsetLeft - liWidth);
            }
            index += 1;
            btnShow(index);
        }
    }
    next.addEventListener("click",nextclick, false);
    
    function btnShow(cur_index) {
        for (var i = 0; i < ol.children.length; i++) {
            ol.children[i].className = ' '; //取消全部li的类
        }
        ol.children[cur_index - 1].className = "current";  //给新的小圆点加上类
    }

    再加上一个计时器,每隔一段时间就会触发一次下一张的效果,来实现轮播

    var timer;
    function play() {
        timer = setInterval(nextclick, 3000)
    }
    
    scroll.addEventListener("load", play(), false);  //整个p全部加载完毕后开始
    
    scroll.addEventListener("mouseenter", function () { //鼠标移入图片是清除计时器
        clearInterval(timer);
    }, false);
    
    scroll.addEventListener("mouseleave", function () {  //鼠标移出图片时再次启动计时器
        play();
    }, false);

    最后给小圆点加上事件,点第几个轮播到第几张

    //小圆点的点击事件
    var olliclick = function () {
        if (flag) {
            flag = false;
            var cur_li = document.getElementsByClassName("current");
            var lastid = cur_li[0].id;  //当前的小圆点是第几个
            var distance = this.id - lastid;  //计算当前小圆点与点击的小圆点的距离(分正负)
            if (distance == 0) {
                flag = true;
            }
            else {
                animate_ol(ul, distance);
            }
        }
    }
    
    //给所有的小圆点添加上点击事件
    var ollitimer = 1
    var lis = ol.getElementsByTagName('li');
    for (ollitimer; ollitimer < lis.length+1; ollitimer++) {
        var olli = document.getElementById(ollitimer);
        olli.addEventListener("click", olliclick, false);
    }
    
    function animate_ol(obj, value) {  //小圆点动画函数
        if (value > 0) {  //判断移动方向
            var speed = -20*value; //使动画时间一致
        }
        if (value < 0) {
            var speed = -20*value;
        }
        var lastleft = obj.offsetLeft;
        obj.timer = setInterval(function () {
            var distance = Math.abs(value * liWidth) - Math.abs(obj.offsetLeft - lastleft);
            //剩余需要移动的距离
            if (distance < Math.abs(speed)) {
                clearInterval(obj.timer);
                if (value > 0) {
                    obj.style.left = obj.offsetLeft - distance + "px";
                    flag = true;
                }
                if (value < 0) {
                    obj.style.left = obj.offsetLeft + distance + "px";
                    flag = true;
                }
            }
            else {
                obj.style.left = obj.offsetLeft + speed + "px";
            }
        }, 1);
        index = index + value;
        btnShow(index);
    }

    再对一下常见的鬼畜bug进行一下总结:
    通过设置flag来防止多次点击造成的计时器冲突,在点击后将flag置为false,在动画函数结束时再置为true,这样只能在上一个点击事件动画结束后才会触发第二次。

    最后放上完整的js代码

    var scroll = document.getElementById("scroll");
    var ul = document.getElementById("ul");
    var ulLis = ul.children;
    var liWidth = ul.children[0].offsetWidth;
    
    var num = ulLis.length - 1;
    ul.appendChild(ul.children[0].cloneNode(true));
    ul.insertBefore(ul.children[num].cloneNode(true), ul.firstChild);
    
    var ol = document.getElementById("olnavi");
    for (var i = 0; i < ulLis.length - 2; i++) {
        var li = document.createElement("li");
        li.id = (i + 1);
        ol.appendChild(li);
        
    }
    ol.children[0].className = "current";
    
    var last = document.getElementById("last");
    last.style.background = "url(images/last-control.png)";
    
    last.addEventListener("mouseenter", function () {
        last.style.background = "url(images/newlast-control.png)";
    }, false);
    
    last.addEventListener("mouseleave", function () {
        last.style.background = "url(images/last-control.png)";
    }, false);
    
    var next = document.getElementById("next");
    next.style.background = "url(images/next-control.png)";
    
    next.addEventListener("mouseenter", function () {
        next.style.background = "url(images/newnext-control.png)";
    }, false);
    
    next.addEventListener("mouseleave", function () {
        next.style.background = "url(images/next-control.png)";
    }, false);
    
    var flag = true;
    var index = 1;
    var lastclick = function () {
        if (flag) {
            flag = false;
            console.log(flag);
            if (index === 1) {
                index = 6;
                ul.style.left = "-5700px";
                animate(ul, ul.offsetLeft + liWidth);
            }
            else {
                animate(ul, ul.offsetLeft + liWidth);
            }
            index -= 1;
            btnShow(index);
        }
    }
    last.addEventListener("click", lastclick, false);
    
    var nextclick = function () {
        if (flag) {
            flag = false;
            if (index === 5) {
                index = 0;
                ul.style.left = "0px";
                animate(ul, ul.offsetLeft - liWidth);
            }
            else {
                animate(ul, ul.offsetLeft - liWidth);
            }
            index += 1;
            btnShow(index);
        }
    }
    next.addEventListener("click",nextclick, false);
    
    function btnShow(cur_index) {
        for (var i = 0; i < ol.children.length; i++) {
            ol.children[i].className = ' ';
        }
        ol.children[cur_index - 1].className = "current";
    }
    
    function animate(obj, target) {
        var speed = obj.offsetLeft < target ? 10 : -10;
        obj.timer = setInterval(function () {
            var result = target - obj.offsetLeft;
            obj.style.left = obj.offsetLeft + speed + "px";            
            if (Math.abs(result) <= Math.abs(speed)) {
                clearInterval(obj.timer);
                obj.style.left = target + "px";
                flag = true;
            }
        }, 1);
    }
    
    var timer;
    function play() {
        timer = setInterval(nextclick, 3000)
    }
    
    scroll.addEventListener("load", play(), false);
    
    scroll.addEventListener("mouseenter", function () {
        clearInterval(timer);
    }, false);
    
    scroll.addEventListener("mouseleave", function () {
        play();
    }, false);
    
    var olliclick = function () {
        if (flag) {
            flag = false;
            var cur_li = document.getElementsByClassName("current");
            var lastid = cur_li[0].id;
            var distance = this.id - lastid;
            if (distance == 0) {
                flag = true;
            }
            else {
                animate_ol(ul, distance);
            }
        }
    }
    var ollitimer = 1
    var lis = ol.getElementsByTagName('li');
    for (ollitimer; ollitimer < lis.length+1; ollitimer++) {
        var olli = document.getElementById(ollitimer);
        olli.addEventListener("click", olliclick, false);
    }
    
    function animate_ol(obj, value) {
        if (value > 0) {
            var speed = -20*value;
        }
        if (value < 0) {
            var speed = -20*value;
        }
        var lastleft = obj.offsetLeft;
        obj.timer = setInterval(function () {
            var distance = Math.abs(value * liWidth) - Math.abs(obj.offsetLeft - lastleft);
            if (distance < Math.abs(speed)) {
                clearInterval(obj.timer);
                if (value > 0) {
                    clearInterval(obj.timer);
                    obj.style.left = obj.offsetLeft - distance + "px";
                    flag = true;
                }
                if (value < 0) {
                    clearInterval(obj.timer);
                    obj.style.left = obj.offsetLeft + distance + "px";
                    flag = true;
                }
            }
            else {
                obj.style.left = obj.offsetLeft + speed + "px";
            }
        }, 1);
        index = index + value;
        btnShow(index);
    }

    相关推荐:

    原生js实现轮播图

    原生javascript实现图片轮播效果代码

    相关文章

    java速学教程(入门到精通)
    java速学教程(入门到精通)

    java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

    下载

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

    相关专题

    更多
    视频文件格式
    视频文件格式

    本专题整合了视频文件格式相关内容,阅读专题下面的文章了解更多详细内容。

    2

    2025.12.31

    不受国内限制的浏览器大全
    不受国内限制的浏览器大全

    想找真正自由、无限制的上网体验?本合集精选2025年最开放、隐私强、访问无阻的浏览器App,涵盖Tor、Brave、Via、X浏览器、Mullvad等高自由度工具。支持自定义搜索引擎、广告拦截、隐身模式及全球网站无障碍访问,部分更具备防追踪、去谷歌化、双内核切换等高级功能。无论日常浏览、隐私保护还是突破地域限制,总有一款适合你!

    6

    2025.12.31

    出现404解决方法大全
    出现404解决方法大全

    本专题整合了404错误解决方法大全,阅读专题下面的文章了解更多详细内容。

    16

    2025.12.31

    html5怎么播放视频
    html5怎么播放视频

    想让网页流畅播放视频?本合集详解HTML5视频播放核心方法!涵盖<video>标签基础用法、多格式兼容(MP4/WebM/OGV)、自定义播放控件、响应式适配及常见浏览器兼容问题解决方案。无需插件,纯前端实现高清视频嵌入,助你快速打造现代化网页视频体验。

    3

    2025.12.31

    关闭win10系统自动更新教程大全
    关闭win10系统自动更新教程大全

    本专题整合了关闭win10系统自动更新教程大全,阅读专题下面的文章了解更多详细内容。

    2

    2025.12.31

    阻止电脑自动安装软件教程
    阻止电脑自动安装软件教程

    本专题整合了阻止电脑自动安装软件教程,阅读专题下面的文章了解更多详细教程。

    1

    2025.12.31

    html5怎么使用
    html5怎么使用

    想快速上手HTML5开发?本合集为你整理最实用的HTML5使用指南!涵盖HTML5基础语法、主流框架(如Bootstrap、Vue、React)集成方法,以及无需安装、直接在线编辑运行的平台推荐(如CodePen、JSFiddle)。无论你是新手还是进阶开发者,都能轻松掌握HTML5网页制作、响应式布局与交互功能开发,零配置开启高效前端编程之旅!

    2

    2025.12.31

    php如何本地部署教程
    php如何本地部署教程

    想在本地搭建PHP开发环境?本合集提供2025最新PHP本地部署详细教程,涵盖Windows、macOS、Linux三大系统,手把手教你安装Apache/Nginx、MySQL、PHP(AMP/LAMP/WAMP集成环境),配置虚拟主机、开启扩展、调试错误等关键步骤。无需联网依赖,快速构建高效本地开发环境,新手也能轻松上手!

    2

    2025.12.31

    小游戏4399大全
    小游戏4399大全

    4399小游戏免费秒玩大全来了!无需下载、即点即玩,涵盖动作、冒险、益智、射击、体育、双人等全品类热门小游戏。经典如《黄金矿工》《森林冰火人》《狂扁小朋友》一应俱全,每日更新最新H5游戏,支持电脑与手机跨端畅玩。访问4399小游戏中心,重温童年回忆,畅享轻松娱乐时光!官方入口安全绿色,无插件、无广告干扰,打开即玩,快乐秒达!

    35

    2025.12.31

    热门下载

    更多
    网站特效
    /
    网站源码
    /
    网站素材
    /
    前端模板

    精品课程

    更多
    相关推荐
    /
    热门推荐
    /
    最新课程
    Bootstrap 5教程
    Bootstrap 5教程

    共46课时 | 2.7万人学习

    前端开发(基础+实战项目合集)
    前端开发(基础+实战项目合集)

    共60课时 | 3.7万人学习

    第二十四期_前端开发
    第二十四期_前端开发

    共161课时 | 4.3万人学习

    关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
    php中文网:公益在线php培训,帮助PHP学习者快速成长!
    关注服务号 技术交流群
    PHP中文网订阅号
    每天精选资源文章推送

    Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号