原生javascript实现无缝轮播图

     2022-03-17     654

关键词:

无缝轮播图是页面常用的特效之一,然而在实际的开发过程中,大部分的开发者都会使用插件来对轮播图进行开发,那么它的底层到底是怎么实现的呢,本文章将围绕这一问题展开探讨。

在讨论如何利用原生JS实现图片之间无缝切换轮播的动画效果之前,我们先来谈谈无缝轮播图片的css布局。

首先我们需要一个用来显示图片的DIV容器,然后把想要轮播的图片没有缝隙的排成一行放入DIV容器中,给DIV容器设置 overflow: hidden,这样在页面中就可以只看到一张图片,然后通过利用JS来移动ul的left值就能达到无缝轮播的动画效果。

然而这还不够,我们还需要在第一张图片前放最后一张图片,以及在最后一张图片后放第一张图片,这样做得目的是为了实现第一张图片和最后一张图片切换时能达到无缝的动画效果。核心代码和布局效果如下:

<div id="box">
    <ul>
        <li><img src="img/5.jpg"></li>
        <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.jpg"></li>
        <li><img src="img/5.jpg"></li>
        <li><img src="img/1.jpg"></li>
    </ul>
</div>

下图是给DIV容器设置overflow: hidden前的效果:

技术分享

 布局搞定之后,接下来就是如何利用原生JS实现无缝轮播。

首先我们需要两个核心的函数,一个用于实现图片无缝切换时的减速运动,另一个用于获取ul的left值(注意:无缝轮播每次移动的都是整个ul的left值)

function fnMove(ele, obj,callback) {
    //参数一:需要动态变化样式的元素
    //参数二:一个对象 其 键为需要变化的css属性名,值为css属性目标值 例{fontSize:500,height:140,opacity:50}
    //参数三:回调如果动画结束 调用该函数

    clearInterval(ele.timer);

    //创建计时器动态的修改 目标元素的css属性值
    // 用ele存储timer 目的不让计时器number被释放,导致无法阻止计时器
    ele.timer = setInterval(function () {

        var fnStop = true; //标记 判断是否所有动画都达到目标值

        for (var attr in obj) { //遍历对象 获取到所有需要修改的属性名和目标值
            var curr = 0;
            // 元素当前css属性值 如果属性是opacity 0 - 1
            // 因为我们的速度大于等于1 直接操作0-1小数不太好操作
            // 我们对他进行放大100倍操作
            if(attr == opacity){
                curr = parseInt(getStyle(ele, attr)*100)
            }else {
                curr = parseInt(getStyle(ele, attr))
            }

            //定义一个速度 让目标元素 每30毫秒增加5像素 直到达到目标值停止计时器(动画结束)
            //减速运动 目标值(不变) - 减去当前值(越来越接近目标) 减出来的结果越来越小 除以6不要让当前值一瞬间达到目标值
            var speed = (obj[attr] - curr)/6;
            //放大动作  0.3 => 1   -0.3 => -1 避免让速度等于0
            speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);

            if(speed != 0){
                fnStop = false;
            }

            // console.log(curr);
            //动态改变css属性值  如果是透明度 我们之前给他乘以100倍 这里需要还原回0-1的数
            if(attr == opacity){
                ele.style[attr] = parseFloat((curr + speed)/100);
                //透明度兼容写法 老版本浏览器透明度为0-100
                ele.style.filter = alpha(opacity:+(curr + speed)+)
            }else {
                ele.style[attr] = curr + speed + px
            }

        }
        //所有动画完成,调用回调函数(可选)
        if (fnStop){
            clearInterval(ele.timer);
            if(callback){
                callback();
            }
        }
    }, 30)

 

function getStyle(ele, sAttr) {
    //参数一:需要获取的元素对象
    //参数二:需要获取的样式属性
    //兼容写法获取 元素css样式的值
    //高版本浏览器getComputedStyle(元素,伪类),不是伪类设为null,返回的是一个CSS样式声明对象
    if (window.getComputedStyle) {
        sAttr = window.getComputedStyle(ele, null)[sAttr];
    } else {
        //低版本浏览器
        sAttr = ele.currentStyle(sAttr);
    }
    return sAttr
}

 

有了这两个方法,实现无缝轮播将变得简单。

首先我们需要一个定时器,让图片每两秒进行一次轮播。其次,我们还需要一个用于移动图片的函数,把该函数放入定时器中,每两秒调用一次,实现轮播效果。

 

 //通过js获取图片/li的宽度,得到每次轮播移动多少像素
 var imgWidth = liList[0].offsetWidth;
 //定义当前轮播图的下标(用来记录下一次该展示第几张图片)
 var index = 1; // 图片从第一张开始 index==0 其实是最后一张图片
 //页面小圆点高亮的下标
 var num = 0;
 //开始进行轮播
 box.timer = setInterval(showRight, 2000);
function showRight() {
    index++;
    num++;
    if (num >= spans.length) { //spans为与展示图片数量相同的小点数组
    num = 0;
    }
    if (index >= liList.length) { //上一次已经展示了第一张(li最后一张)了,该展示第二张
     // 直接设置css属性left 是没有动画效果的 无缝的让最后一张跳回 第1张
    ul.style.left = -imgWidth + ‘px‘;
    //改变index值 动画效果的让第一张移动到第二张
    index = 2;
    }
    fnMove(ul, {left: -imgWidth * index})
    activeSpan(num);  //点亮与图片相对应的小圆点
}
//高亮小圆点方法
function activeSpan(num) {
    for (var i = 0; i < spans.length; i++) {
    spans[i].className = ‘‘;
    }
    spans[num].className = ‘bgcolor‘
}

 

效果图:

技术分享

 

接下来给左右按钮绑定点击事件,右按钮每次点击就是调用一次showRight()函数,有了showRight()函数,showLeft()函数也很容易编写出来(注意:每次点击需要清除原来进行轮播的定时器):

left.onclick = function (e) {
     //阻止事件冒泡的兼容写法
      e = e || window.event;
      window.event ? e.cancelBubble = true : e.stopPropagation();
      clearInterval(box.timer);
      showLeft();
      }

right.onclick
= function (e) { e = e || window.event; window.event ? e.cancelBubble = true : e.stopPropagation(); clearInterval(box.timer); showRight(); }

效果图(实际有鼠标在对左右按钮进行点击

技术分享

 

 

最后利用for循环给每个小圆点绑定点击事件,这里涉及到JS一个特性:异步事件队列。

在这里简单解释一下:页面加载时是从上往下地对代码进行同步加载,当遇到需要事件触发的回调函数时,JS会把该回调函数丢入异步事件队列当中,然后继续往下加载代码。当页面中有事件被触发时,JS会从异步事件队列中调用与该事件绑定的所有回调函数。

所以,在利用for循环给每个小圆点绑定点击事件时,我们需要记录下每个小圆点的下标,在调用与点击小圆点事件绑定的回调函数中读取与小圆点对应的下标。

//给小圆点添加点击
function spansClick() {
    for (var i = 0; i < spans.length; i++) {
        //记录每个小圆点的下标
        spans[i].index=i;
        spans[i].onclick = function (e) {
            e = e || window.event;
            window.event ? e.cancelBubble = true : e.stopPropagation();
            //读取每个小圆点的下标
            num = this.index;
            index = num + 1; //index永远比num大1
            activeSpan(num);
            fnMove(ul, {left: -imgWidth * index})
        }
    }
}

效果图(实际有鼠标对小圆点进行点击

技术分享



js原生javascript轮播图渐变淡入淡出效果实现(附代码)(代码片段)

目录前言轮播图的组成以及实现思想左右按钮的隐藏与显示核心思想 代码实现 动态生成底部小圆圈核心思想代码实现     右左按钮实现核心思想代码实现实现自动播放核心思想代码实现整体代码(复制可用)总结前... 查看详情

用原生的javascript实现一个无限滚动的轮播图

说一下思路:和我上一篇博客中用JQ去写的轮播图有相同点和不同点相同点:首先页面布局是一样的同样是改变.inner盒子的位置去显示不同的图片不同点:为了实现无限滚动需要多添加两张重复的图片左右切换和前面的方法有所... 查看详情

javascript:100%原生js实现左右切换的轮播图(无延迟加载)

<!--说明:此.html文件必需有:(1)同级文件夹json,json文件夹下必需有文件data.txt,文件data.txt的内容为:[{"imgSrc":"img/banner1.jpg"},{"imgSrc":"img/banner2.jpg"},{"imgSrc":"img/banner3.jpg"},{"imgSrc":"img/banner4.jpg"}](2)同级文件夹img 查看详情

javascript:100%原生js实现左右切换的轮播图(有延迟加载)

<!--说明:此.html文件必需有:(1)同级文件夹json,json文件夹下必需有文件data.txt,文件data.txt的内容为:[{"imgSrc":"img/banner1.jpg"},{"imgSrc":"img/banner2.jpg"},{"imgSrc":"img/banner3.jpg"},{"imgSrc":"img/banner4.jpg"}](2)同级文件夹img 查看详情

js原生选项(自动播放无缝滚动轮播图)二

今天分享一下自动播放轮播图,自动播放轮播图是在昨天分享的轮播图的基础上添加了定时器,用定时器控制图片的自动切换,函数中首先封装一个方向的自动播放工能的小函数,这个函数中添加定时器,定时器中可以放向右走... 查看详情

焦点轮播图效果实现

  焦点轮播图相对前面讲的逐帧轮播图实现多了两个功能,1、图片轮播可以手动滚动(新增左右箭头),这里重点是实现向左滚动的无缝连接。2、多了下方小圆点,指示图片播放位置,并可以点击小圆点跳转。  那么如何... 查看详情

逐帧轮播图效果实现

  所谓逐帧轮播图就是一帧一帧的移动播放,并且实现无缝接连播放的效果。下面将介绍逐帧轮播图的实现思路。  该效果的重点是如何实现无缝连接,其实很简单,逐帧轮播图都是从右往左移动,那么只需将最后一幅轮播... 查看详情

jquery简单无缝轮播图实现

...图片列表的第一张图片,添加到图片列表ul的末尾。这样实现了,图片自动播放的效果。 怎么带动图片控制的小按钮变亮? 因为每一次图片轮播,都会改变图 查看详情

简洁原生js实现轮播图

html:<divclass="comiis_wrapad"id="slideContainer"><divid="frameHlicAe"class="framecl"><divclass="temp"></div><divclass="block"><divclass="cl"><ulclass="slideshow 查看详情

js原生选项卡(包含移动端无缝选项卡)三

今天分享下移动端原生js的无缝轮播图;移动端尽量减少使用DOM操作来频繁的浪费移动端设备的性能,所以这个无缝轮播图更多的使用了transition和transform,无缝的思想和昨天分享的PC端的无缝轮播的思想是一样的,分别在正常的... 查看详情

轮播图采用jsjquery实现无缝滚动和非无缝滚动的四种案例实现,兼容ie低版本浏览器(代码片段)

项目源代码下载地址:轮播图以下为项目实现效果:(由于gif太大,所以只上传一张图片,但效果完全能实现,经测试,在ie各版本浏览器及chrome,firefox等浏览器中均能实现效果,可以实现点击切换图片,无缝滚动和非无缝滚动... 查看详情

纯原生javascript仿网易轮播图

  第一次有自己的关于代码的博客,感到诚惶诚恐。这可能是我第一次以程序猿,或者连初级程序猿都不是的身份下开通的个人“技术”(胡写乱写)博客园地。闲言碎语不要讲,咱今天就写一点关于js的代码吧。... 查看详情

原生js-实现轮播图效果(代码片段)

前言:原生js实现轮播图,效果虽丑,但是达到了想要的效果。js代码放在本页面,全部的代码点击链接下载https://download.csdn.net/download/TroyeSivanlp/43150377实现轮播图效果效果js代码效果js代码window.addEventListener('load... 查看详情

使用js和css-transition属性57行代码实现简易无缝轮播图

代码如下:<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metahttp-equiv="X-UA-Compatible"content="IE=edge"><metaname="viewport"content="width=device-width,initial 查看详情

原生javascript之实战轮播图(代码片段)

成品效果如下图所示:因为博客园限制图片上传大小被我删了一些帧数,所以图片看起来会有一点卡,现实运行是不会的 搭建HTML和CSS结构HTML代码如下:1<divclass="wrapper">2<ulclass="sliderPage">3<li>4<imgsrc="images/1.jpg"&... 查看详情

原生javascript手写一个丝滑的轮播图(代码片段)

通过本文,你将学到:htmlcssjs没错,就是html,css,js,现在是框架盛行的时代,所以很少会有人在意原生三件套,通过本文实现一个丝滑的轮播图,带你重温html,css和js基础知识。为什么选用轮播图做示例?... 查看详情

js实现轮播图效果(附源码)--原生js的应用

1.js实现轮播图效果<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="Author"content="奇客艺术"><metaname="keyword"content="关键字"><metaname="description"conte 查看详情

jquery实现轮播图效果(代码片段)

...就是轮播图,首先我用jquery写了一个,第二篇我会用原生JavaScript给大家展示。其原理是一样的,只不过jquery封住好了一些属性和方法。获取节点和实现效果就比较方便快捷了。下面是展示代码和介绍:html部分代码:<divclass="sl... 查看详情