整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

利用JavaScript jQuery实现图片无限循

利用JavaScript jQuery实现图片无限循环轮播(不借助于轮播插件)

  作为一个前端工程师,无论公司是什么行业,无论你做什么端,基本都会遇到一个避不开的动画效果:循环轮播。做轮播并不难,市场上的轮播插件有很多,其中比较著名的是swiper,使用也非常简单。但轮播插件这种东西总归是不灵活的,一些简单的场景还可以应付,比较复杂一点的场景处理起来就比较麻烦了。今天我会全程带大家来写一个循环轮播,用到的技术有:html、css、JavaScript、jQuery,都是前端最基础的技术,有基础又爱学肯学的你一定一听就会,如果不会咋整?那多看几遍。

  1. 效果展示

  以小米官网的图片轮播为例,实际上千篇一律,好啦,看下图:

   好啦,看效果,不要看妹子,虽然妹子长得是很好看啦!

  2. 原理分析

  无限循环轮播的原理是在展示内容的前后各放一组图片,以无限循环展示3张照片为例,三张图片我给它取名为1.jpg,2.jpg,3.jpg,图片展示分别如下:

  原理示意图展示:

  原理其实就是复制两组同样的照片分别放在前面和后面(实际上不用完全复制两组,只需要前面可以看到1.jpg,后面也可以到1.jpg就好了,但这里我为了方便大家理解,就采用这样的方式了)。当点左边按钮,图片轮播到第一张1.jpg时,让盛放图片的容器瞬间拉回到第二张1.jpg照片的位置,注意一定要是瞬间。同理,当点右边按钮时,图片轮播到第三张1.jpg的时候,也让盛放图片的容器瞬间拉回到第二张1.jpg照片的位置。这是实现图片循环轮播的关键,稍后会仔细讲解。

  3. 代码

  html代码:

<div class="slideImageContainer">
    <div class="slideImageLists">
        <img src="1.jpeg" />
        <img src="2.jpeg" />
        <img src="3.jpeg" />
        <img src="1.jpeg" />
        <img src="2.jpeg" />
        <img src="3.jpeg" />
        <img src="1.jpeg" />
        <img src="2.jpeg" />
        <img src="3.jpeg" />
    </div>
    <div class="slideLeftBtn" id="slideLeftBtn"></div>
    <div class="slideRightBtn" id="slideRightBtn"></div>
</div>

  css 代码:

*{
    padding: 0;
    margin: 0;
}
@font-face {
    font-family: 'iconfont';  /* project id 208314 */
    src: url('//at.alicdn.com/t/font_208314_2l9oi1sn4hmh1tt9.eot');
    src: url('//at.alicdn.com/t/font_208314_2l9oi1sn4hmh1tt9.eot?#iefix') format('embedded-opentype'),
    url('//at.alicdn.com/t/font_208314_2l9oi1sn4hmh1tt9.woff') format('woff'),
    url('//at.alicdn.com/t/font_208314_2l9oi1sn4hmh1tt9.ttf') format('truetype'),
    url('//at.alicdn.com/t/font_208314_2l9oi1sn4hmh1tt9.svg#iconfont') format('svg');
}
.slideImageContainer{
    position: relative;
    width: 600px;
    height: 300px;
    margin: 0 auto;
    border: solid 1px red;
    overflow: hidden;
}
.slideImageLists{
    position: absolute;
    left: -1800px;
    top: 0;
    width: 10000px;
    height: 300px;
}
.slideImageLists img{
    display: block;
    width: 600px;
    height: 300px;
}
.slideLeftBtn,.slideRightBtn{
    position: absolute;
    font-family: "iconfont";
    font-size: 60px;
    top: 120px;
    color: #191f25;
    opacity: 0.3;
    cursor: pointer;

    user-select: none;  
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
}
.slideLeftBtn:hover,.slideRightBtn:hover{
    opacity: 0.6;
}
.slideLeftBtn{
    left: 10px;
}
.slideRightBtn{
    right: 10px;
}

  页面布局是很重要的一部分内容,它是页面的基石。页面布局写得好实现效果的时候能带来很大的方便。因此这里强调几个应该注意的地方:

  1. 所有的图片要放在一个很长的容器中,这里是slideImageList,每次移动实际上就是它在相对于他的父元素slideImageContainer而移动,所以需要给slideImageContainer 一个 position:relative 的定位,给 slideImageList 一个 position: absoluete 的定位。

  2. slideImageList要放在一个比较小的容器中,在这里是slideImageContainer,作用是为了显示你想要显示的区域,注意要加 overflow:hidden 属性,让多余的内容不显示。

  3. 左右按钮我采用的是iconfont的使用方式,这个比较简单,此处不多加以阐述。不会使用iconfont的同学可以直接贴两个图片或者左右箭头符号在上面。

  4. 容器slideImageList中的图片要排列在一条直线上,并且初始情况下需要给slideImageList一个left值,因为最开始我们想让第四张照片展示,所以此时的left值为-1800px,要记住这个值,因为我们待会儿要常用到这个值。

  5. @font-face 是引入 iconfont 相关的资源内容,不使用iconfont的可忽略。

  接下来看javascript代码:

var slideIndex=3;   //记录初始图片的下标( 默认最初展示第四张图片,下标从0开始,所以初始值为3 )
//左边按钮的点击事件
$("#slideLeftBtn").on("click",function(){
    // 点击左按钮的时候想要显示当前图片的前一张,所以slideIndex值要减去1
    slideIndex--;
    // animateLength表示想要让slideImageLists移动到什么位置,slideImageLists 的位置由 left属性来控制
   var animateLength=slideIndex * (-600) + "px";
    $(".slideImageLists").animate({"left":animateLength},"slow",function(){
        // animate的回调函数(即执行完动画之后才会执行函数里面的内容)
        if(slideIndex <=0){
            $(".slideImageLists").css({"left":"-1800px"});
            slideIndex=3;
        }
    });
})
//右边按钮的点击事件
$("#slideRightBtn").on("click",function(){
    // 点击右按钮的时候想要显示当前图片的后一张,所以slideIndex值要加上1
    slideIndex++;
    var animateLength=slideIndex * (-600) + "px";
    $(".slideImageLists").animate({"left":animateLength},"slow",function(){
     if(slideIndex >=6){
            $(".slideImageLists").css({"left":"-1800px"});
            slideIndex=3;
        }
    })
})

  现在着重来分析一下JavaScript的代码,同样有几个关键点需要注意,其中部分我已在代码中注释:

  1. 全局变量 slideIndex 指的是图片的下标,一共有九张照片,下标从0开始,所以九张照片的下标值分别为0-8,此处我们默认展示第四张照片,所以slideIndex 的初始值置为 3 。另外需要注意的是,slideIndex 是全局变量,所以函数内函数外都可以访问到,并且只初始化一次。

  2. 局部变量 animateLength 指的是想要 slideImageLists 运动到的位置,注意要加单位,并且需要赋值给 slideImageList 的 left 属性。

  3. jQuery的 animate 方法 ,详情见下图:

  接下来完整地分析一下流程,以点击左按钮为例:

  1. 初始情况下展示第四张图片,下标为 3 。 ( var slideIndex=3 )

  2. 给左按钮绑定一个点击事件

  3. 点击左按钮的时候,想要展示当前照片的前一张,所以图片下标需要减去1 ( slideIndex-- )

  4. 计算 slideImageLists 要移动的位置 ( slideIndex * (-600) + "px" ),记得加单位。为什么要乘以 -600 ,首先 600 是一张照片的宽度,上面我们分析过了如果要默认展示第四张照片的话 slideImageLists 的 left 属性值为 -1800px,同理,点击左按钮,想要展示第三张照片,那么此时需要 slideImageLists 的 left 属性值为 -1200px,所以就是 ( 3 - 1 ) * ( -600 ) + "px"=-1200px 。

  5. 利用 animate 来执行动画。将上一步计算出来的值赋值给 slideImageLists 的 left 属性。注意 animate方法本身就是含有过渡的,所以切记不需要在 slideImageLists 上面再加 transtion 属性来实现过渡。

  6. 实现循环轮播的重点来了。以上步骤实现了轮播,但没有实现循环轮播,回忆我们刚才讲的内容,一共有三组 1.jpg、2.jpg、3.jpg 这张照片,默认展示第四张照片,也就是第二组照片中的 1.jpg ,如果点击左按钮,会分别展示第一组照片中的 3.jpg 、2.jpg、1.jpg , 假设一直点击左按钮,展示到第一张照片,也就是第一组的 1.jpg 的时候,此时图片的下标 slideIndex 的值为 0 。当此时展示的图片的下标 slideIndex 的值为 0 并且执行完这个动画的时候,我们需要做一个操作,将 slideImageLists 的 left 值瞬间改变为 -1800px,这个值我们上面强调过了,是初始情况下展示第四张照片也就是第二组中的 1.jpg 的时候 slideImageLists 的 left 值,并且将当前展示的图片的下标 slideIndex 的值变为 3 。

  animate有一个非常方便的地方在于他提供了一个回调函数,回调函数在动画执行完之后自己执行。

  另外,这里还有一个需要格外注意的地方,我们一直强调一定要瞬间将 slideImageLists 拉回到 left 值为 -1800px 的地方,那是因为如果也类似于用animate来实现的话用户会看到一个动画的过程,这是我们不能接受的。所以在瞬间拉回的时候我采用的是jQuery的css方法去改变 left 属性。

  不完美的地方

  但是讲到这里,实际上还是有不完美的地方,如果你多次点击按钮,就会发生错乱,此时我们需要做的是在动画的执行过程中点击按钮无效,只有动画结束完成才可以继续点击实现动画。我这里采用的方案是引入一个布尔类型的变量 isClickable,初始值为true,表示初始情况下可点击。当用户点击按钮的时候会进行判断当前 isClickable 的值,如果值为true的时候才会去执行 slideIndex-- 的操作,否则会 return false ,不会再执行下面的代码。

  此时我们来分析一下流程:

  1. 初始情况下isClickable的值为true,表示当前按钮是可以点击的。

  2. 此时我们去点击左按钮,isClickable 的值为 true , 会执行slideIndex-- 的操作。并且将 isClickable的值设置为 false,表示现在已经处在动画中。此时再去点击左按钮就无法再执行slideIndex--的操作,而是进入 return false,终止当前代码。

  3. 需要注意的是,我们需要在动画执行完成后,也就是在回调函数中将 isClickable 的值变为 true,所以当动画结束后再点击按钮的时候就可以进行下一次动画了。

  具体代码如下:

var isClickable=true;   // 是否可点击,默认可点击
var slideIndex=3;   
$("#slideLeftBtn").on("click",function(){
    if(isClickable==true){
        slideIndex--;
    }else{
        return false;
    }
    isClickable=false;
    var animateLength=slideIndex * (-600) + "px";
    $(".slideImageLists").animate({"left":animateLength},"slow",function(){
        isClickable=true;
        if(slideIndex <=0){
            $(".slideImageLists").css({"left":"-1800px"});
            slideIndex=3;
        }
    });
})
xxxxxxxxxxbr var isClickable=true;   // 是否可点击,默认可点击brvar slideIndex=3;   br$("#slideLeftBtn").on("click",function(){br    if(isClickable==true){br        slideIndex--;br    }else{br        return false;br    }br    isClickable=false;br    var animateLength=slideIndex * (-600) + "px";br    $(".slideImageLists").animate({"left":animateLength},"slow",function(){br        isClickable=true;br        if(slideIndex <=0){br            $(".slideImageLists").css({"left":"-1800px"});br            slideIndex=3;br        }br    });br})

  以上就是左按钮点击时候的思路,点击右按钮的思路和点击左按钮的思路是一样的,相信聪明的你一定能够一点即通,有问题欢迎大家和我交流。

  祝工作顺利 ~

限轮播图效果

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title>50-jquery无限循环滚动图片</title>

<style type="text/css">

*{

margin: 0; /*外边距:0*/

padding: 0; /*内边距:0*/

}

div{

width: 600px; /*宽:600*/

height: 160px; /*高:160*/

border: #000000 solid 1px; /*边框:黑色 实线 1像素*/

margin: 100px auto; /*外边距:上100像素 左右自动居中*/

position: relative; /*定位:相对定位*/

overflow: hidden; /*溢出:隐藏*/

}

ul{

list-style: none; /*列表样式:无点*/

width: 2100px; /*宽:2100*/

height: 160px; /*高:160*/



}

ul>li{

float: left; /*浮动布局:左浮动*/


}

</style>

<script src="../static/js/jquery-3.6.0.js"></script>

<script>

$(function(){

var pianyi=0; // 定义一个偏移量为0

var timer=setInterval(function(){ // 定义一个定时器 50毫秒调用一次

if(pianyi>-1500){ // 如果偏移量大于 -1500

$('ul').css('margin-left', pianyi) // 把ul的样式的左边距设置成偏移量

pianyi -=5 // 偏移量每次减5

}else{pianyi=0} // 否则(偏移量等于0)

}, 50)


})

</script>

</head>

<body>

<div>

<ul class="ul1">

<li><img src="../static/image/1.jpeg" width="300px" height="160px"></li>

<li><img src="../static/image/2.jpeg" width="300px" height="160px" ></li>

<li><img src="../static/image/3.jpeg" width="300px" height="160px" ></li>

<li><img src="../static/image/4.jpeg" width="300px" height="160px" ></li>

<li><img src="../static/image/5.jpeg" width="300px" height="160px" ></li>

<li><img src="../static/image/1.jpeg" width="300px" height="160px"></li>

<li><img src="../static/image/2.jpeg" width="300px" height="160px" ></li>

</ul>


</div>

</body>

</html>

js2flowchart 是一个可视化库,可将任何JavaScript代码转换为漂亮的SVG流程图。你可以轻松地利用它学习其他代码、设计你的代码、重构代码、解释代码。这样一个强大的神器,真的值得你拥有,看下面截图就知道了,有没有很强大。

Github

https://github.com/Bogdan-Lyashenko/js-code-to-svg-flowchart

安装使用

  • 安装
yarn add js2flowchart
  • 使用

index.html

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title>fly测试</title>
</head>
<body>
 <div style="width:50%;float:left">
 <p id="svgImage"></p>
 </div>
 <div style="width:50%;float:left">
 <textarea name="" id="jsContent" style="width: 90%;height:900px" oninput="createSVG()">
 </textarea>
 </div>
 <script src="./node_modules/js2flowchart/dist/js2flowchart.js"></script>
 <script src="./index.js"></script>
</body>
</html>

index.js

createSVG=()=> {
 document.getElementById("svgImage").innerHTML=null;
 let code=document.getElementById("jsContent").value;
 const { createFlowTreeBuilder, createSVGRender }=js2flowchart;
 const flowTreeBuilder=createFlowTreeBuilder(),
 svgRender=createSVGRender();
 const flowTree=flowTreeBuilder.build(code),
 shapesTree=svgRender.buildShapesTree(flowTree);
 const svg=shapesTree.print();
 document.getElementById("svgImage").innerHTML=svg;
};
createSVG();

我们直接在文本域中输入自己的代码,如下,左边会直接生成流程图,这只是一个简单的示例:

js2flowchart的特性以及适用场景(来自官网翻译)

js2flowchart获取您的JS代码并返回SVG流程图,适用于客户端/服务器,支持ES6。

主要特点:

  • 定义抽象级别以仅渲染导入/导出,类/函数名称,函数依赖性以逐步学习/解释代码。
  • 自定义抽象级别支持创建自己的抽象级别
  • 表示生成器,以生成不同抽象级别的SVG列表
  • 定义流树修改器以映射众所周知的API,例如[] .map,[]。forEach,[] .filter到方案上的循环结构等。
  • 销毁修饰符,用于在方案上用一个形状替换代码块
  • 自定义流树修改器支持创建自己的流修改器
  • 流树忽略过滤器完全省略一些代码节点,如日志行
  • 聚焦节点或整个代码逻辑分支突出显示方案的重要部分
  • 模糊节点或整个代码逻辑分支以隐藏不太重要的东西
  • 定义的样式主题支持选择您喜欢的样式
  • 自定义主题支持创建自己的主题,更好地适合您的上下文颜色
  • 自定义颜色和样式支持提供方便的API来更改特定样式而无需样板

用例场景:

  • 通过流程图解释/记录您的代码
  • 通过视觉理解学习其他代码
  • 为有效JS语法简单描述的任何进程创建流程图

以上所有功能可以直接到github上详细了解,用法太多,这里就不在介绍了!

vscode扩展

这么强大的东西,有人肯定说如果在开发的时候实时看到流程图有助于理解代码,官网提供了插件(我在最新版中测试失效了,不知道是否是我使用的有问题还是插件本身的问题),如果感兴趣的可以到扩展商店搜索code-flowchart。如果测试成功,欢迎到评论区分享。以下是我vscode版本和官网的插件使用截图。

如果利用好这个插件,可以开发出Chrome插件,以及其他JavaScript编辑器或者IDEA的插件,由于官方github已经几个月没更新了,所以还不知道未来会不会支持!

总结

js2flowchart是一个比较实用的Javascript插件,可以用来做很多事情,不管是自己写代码。还是阅读别人的代码,都无疑是一大助力,能够帮助我们提升我们的代码能力,更容易的阅读代码,这样学习起来就快了,希望对你有所帮助!如果有什么好的建议,也可以到评论区分享!