• 原生JavaScript实现轮播图


    ---恢复内容开始---

    实现原理

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

    HTML:

     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4     <meta charset="utf-8" />
     5     <link rel="stylesheet" type="text/css" href="StyleSheet.css">
     6     <title></title>
     7 </head>
     8 <body>
     9     <div id="scroll" class="scroll">
    10         <div id="box" class="box">
    11             <ul id="ul" style="left:-950px;">
    12                 <li><img src="images/top_banner_bw01.jpg" width="950" height="438"></li>
    13                 <li><img src="images/top_banner_bw02.jpg" width="950" height="438"></li>
    14                 <li><img src="images/top_banner_bw03.jpg" width="950" height="438"></li>
    15                 <li><img src="images/top_banner_bw04.jpg" width="950" height="438"></li>
    16                 <li><img src="images/top_banner_bw05.jpg" width="950" height="438"></li>
    17             </ul>
    18             <ol id="olnavi"></ol>
    19         </div>
    20         <div id="last"></div>
    21         <div id="next"></div>
    22     </div>
    23     <script src="a.js"></script>
    24 </body>
    25 </html>

    CSS:

     1 body, div, p,
     2 h1, h2, h3, h4, h5, h6,
     3 dl, dt, dd, ul, ol, li,
     4 table, caption, th, td,
     5 form, fieldset, input, textarea, select,
     6 pre, address, blockquote,
     7 embed, object {
     8     margin: 0px;
     9     padding: 0px;
    10 }
    11 
    12 ul, ol {
    13     list-style:none;
    14 }
    15 
    16 img {
    17     vertical-align: top;
    18 }
    19 
    20 .scroll {
    21      950px;
    22     height: 438px;
    23     margin: auto;
    24     overflow: hidden;
    25     position: relative;
    26 }
    27 
    28 .box {
    29      950px;
    30     height: 438px;
    31     overflow: hidden;
    32     position: relative;
    33 }
    34 
    35 .box ul{
    36      700%;
    37     position: absolute;
    38     left: 0;
    39     top: 0;
    40     padding:0px;
    41     margin:0px;
    42 }
    43 
    44 .box ul li{
    45     float: left;
    46 }
    47 
    48 .scroll ol {
    49     position: absolute;
    50     right: 365px;
    51     bottom: 5px;
    52 }
    53 
    54 .scroll ol li {
    55     float: left;
    56      20px;
    57     height: 20px;
    58     border-radius: 50%;
    59     background: #000;
    60     margin-left: 10px;
    61     cursor: pointer;
    62     opacity: 0.5;
    63 }
    64 
    65 .scroll ol li.current {
    66     background-color: #000099;
    67     opacity: 0.8;
    68 }
    69 
    70 #last {
    71     position: absolute;
    72     bottom: 179px;
    73      80px;
    74     height: 80px;
    75     cursor: pointer;
    76 }
    77 
    78 #next {
    79     position: absolute;
    80     bottom: 179px;
    81     right: 0px;
    82      80px;
    83     height: 80px;
    84     cursor: pointer;
    85 }

    JavaScript:

      1 //1.先获取html中的元素
      2 var scroll = document.getElementById("scroll");
      3 var ul = document.getElementById("ul");
      4 var ulLis = ul.children;
      5 var liWidth = ul.children[0].offsetWidth;
      6 //2.再此之前,我们要明白,小圆点并不是写死的,它是根据ul li中的图片张数来决定的 。
      7 var ol = document.getElementById("olnavi");
      8 for (var i = 0; i < ulLis.length - 2; i++) {
      9     var li = document.createElement("li");
     10     li.id = (i + 1);  //id用于后面为li添加事件
     11     ol.appendChild(li);
     12     
     13 }
     14 ol.children[0].className = "current" //将第一个小圆点设置为触发状态
     15 //3.要实现无缝滚动 就需要多两张图片才行 ,即克隆第一张图片,放到最后一张的后面,克隆最后一张,放到第一张的前面。
     16 var num = ulLis.length - 1;
     17 ul.appendChild(ul.children[0].cloneNode(true));
     18 ul.insertBefore(ul.children[num].cloneNode(true), ul.firstChild);
     19 //4.接下来为左右箭头添加事件,鼠标放到箭头上会变色
     20 var last = document.getElementById("last");
     21 last.style.background = "url(./img/left.png)";
     22 last.style.width = "64px";
     23 
     24 last.addEventListener("mouseenter", function () {
     25     last.style.background = "url(./img/newleft.png)";
     26 }, false);
     27 
     28 last.addEventListener("mouseleave", function () {
     29     last.style.background = "url(./img/left.png)";
     30 }, false);
     31 
     32 var next = document.getElementById("next");
     33 next.style.background = "url(./img/right.png)";
     34 next.style.width = "64px";
     35 
     36 next.addEventListener("mouseenter", function () {
     37     next.style.background = "url(./img/newright.png)";
     38 }, false);
     39 
     40 next.addEventListener("mouseleave", function () {
     41     next.style.background = "url(./img/right.png)";
     42 }, false);
     43 // 5.我们接着用js做动画 动画部分包括: 
     44 // ①.鼠标点击第几个小圆点,就要展示第几张图片,并且小圆点的颜色也发生变化.
     45 // ②. 鼠标点击左右箭头,图片向左右移动一张
     46 // ③图片自动轮播,(这需要一个定时器)
     47 // ④.鼠标放在图片上,图片停止自动播放(这需要清除定时器)
     48 // ⑤.鼠标离开图片,图片继续自动轮播 (重新开始定时器) 
     49 // 这里我们封装了一个animate()动画函数
     50 function animate(obj, target) {  //obj为需要移动的元素,在本文中为ul,target为需要移动到的位置
     51     var speed = obj.offsetLeft < target ? 10 : -10;  //判断速度向左还是向右
     52     obj.timer = setInterval(function () {  //计时器每隔一定时间移动一次
     53         var result = target - obj.offsetLeft;  //剩余需要移动的距离
     54         obj.style.left = obj.offsetLeft + speed + "px";  //改变元素的left来实现移动          
     55         if (Math.abs(result) <= Math.abs(speed)) {  //当需要移动的距离小于速度时
     56             clearInterval(obj.timer);   //清除计时器
     57             obj.style.left = target + "px";  //直接移动到需要移动的位置
     58             flag = true;  //将flag置为true,使点击事件能再次触发
     59         }
     60     }, 1);
     61 }
     62 //6.接下来把动画函数赋给左右箭头
     63 var flag = true;  //用于判断上一个事件是否执行完毕,如果没有执行完毕禁止再次触发事件
     64 var index = 1;  //是第几个小圆点
     65 var lastclick = function () {
     66     if (flag) {
     67         flag = false;  //进入事件将flag置为false
     68         console.log(flag);
     69         if (index === 1) {  //判断是否为第一张
     70             index = 6;
     71             ul.style.left = "-5994px";  //当移动到第一张时,再向右移前会替换到最后一张后面的第一张,然后再向右移动。
     72             animate(ul, ul.offsetLeft + liWidth); //动画函数一次向有移动一个图片长度的距离
     73         }
     74         else {
     75             animate(ul, ul.offsetLeft + liWidth);
     76         }
     77         index -= 1; //移动小圆点计数器
     78         btnShow(index);  //给新的小圆点高亮,取消上一个小圆点的高亮
     79     }
     80 }
     81 last.addEventListener("click", lastclick, false);  //将函数赋给点击事件
     82 
     83 var nextclick = function () {  //向左移与向右移类似
     84     if (flag) {
     85         flag = false;
     86         if (index === 5) {
     87             index = 0;
     88             ul.style.left = "0px";
     89             animate(ul, ul.offsetLeft - liWidth);
     90         }
     91         else {
     92             animate(ul, ul.offsetLeft - liWidth);
     93         }
     94         index += 1;
     95         btnShow(index);
     96     }
     97 }
     98 next.addEventListener("click",nextclick, false);
     99 
    100 function btnShow(cur_index) {
    101     for (var i = 0; i < ol.children.length; i++) {
    102         ol.children[i].className = ' '; //取消全部li的类
    103     }
    104     ol.children[cur_index - 1].className = "current";  //给新的小圆点加上类
    105 }
    106 //7.再加上一个计时器,每隔一段时间就会触发一次下一张的效果,来实现轮播
    107 var timer;
    108 function play() {
    109     timer = setInterval(nextclick, 3000)
    110 }
    111 
    112 scroll.addEventListener("load", play(), false);  //整个div全部加载完毕后开始
    113 
    114 scroll.addEventListener("mouseenter", function () { //鼠标移入图片是清除计时器
    115     clearInterval(timer);
    116 }, false);
    117 
    118 scroll.addEventListener("mouseleave", function () {  //鼠标移出图片时再次启动计时器
    119     play();
    120 }, false);
    121 
    122 //8.最后给小圆点加上事件,点第几个轮播到第几张
    123 //小圆点的点击事件
    124 var olliclick = function () {
    125     if (flag) {
    126         flag = false;
    127         var cur_li = document.getElementsByClassName("current");
    128         var lastid = cur_li[0].id;  //当前的小圆点是第几个
    129         var distance = this.id - lastid;  //计算当前小圆点与点击的小圆点的距离(分正负)
    130         if (distance == 0) {
    131             flag = true;
    132         }
    133         else {
    134             animate_ol(ul, distance);
    135         }
    136     }
    137 }
    138 
    139 //给所有的小圆点添加上点击事件
    140 var ollitimer = 1
    141 var lis = ol.getElementsByTagName('li');
    142 for (ollitimer; ollitimer < lis.length+1; ollitimer++) {
    143     var olli = document.getElementById(ollitimer);
    144     olli.addEventListener("click", olliclick, false);
    145 }
    146 
    147 function animate_ol(obj, value) {  //小圆点动画函数
    148     if (value > 0) {  //判断移动方向
    149         var speed = -20*value; //使动画时间一致
    150     }
    151     if (value < 0) {
    152         var speed = -20*value;
    153     }
    154     var lastleft = obj.offsetLeft;
    155     obj.timer = setInterval(function () {
    156         var distance = Math.abs(value * liWidth) - Math.abs(obj.offsetLeft - lastleft);
    157         //剩余需要移动的距离
    158         if (distance < Math.abs(speed)) {
    159             clearInterval(obj.timer);
    160             if (value > 0) {
    161                 obj.style.left = obj.offsetLeft - distance + "px";
    162                 flag = true;
    163             }
    164             if (value < 0) {
    165                 obj.style.left = obj.offsetLeft + distance + "px";
    166                 flag = true;
    167             }
    168         }
    169         else {
    170             obj.style.left = obj.offsetLeft + speed + "px";
    171         }
    172     }, 1);
    173     index = index + value;
    174     btnShow(index);
    175 }

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

    内容:html+css
  • 相关阅读:
    kubernetes数据持久化
    下拉框联动
    [Ubuntu/系统时间] 系统时间相关
    [Ubuntu] 文件共享
    js 计算对象数组中某个属性合计
    信创环境经典版SuperMap iManager监控外部SuperMap iServer资源失败,无法监控目标GIS服务器CPU与内存使用情况
    K8S命名空间处于Terminating状态,如何强制删除
    信创环境经典版SuerMap iManager启动崩溃
    Vue 3 + Vite + SuerMap iClient构建报错Uncaught TypeError utils.inherits is not a function
    SuperMap iManager for K8S 删除旧环境修改NFS地址流程
  • 原文地址:https://www.cnblogs.com/mingdao/p/lunbo.html
Copyright © 2020-2023  润新知