如何使用JavaScript实现无缝滚动自动播放轮播图效果


Posted in Javascript onAugust 20, 2020

在一些项目开发中,我们经常需要使用到轮播图,但是没有深入学习的情况下做轮播图是非常困难的。

如何使用JavaScript实现无缝滚动自动播放轮播图效果

思路

分成小问题来解决

1. 动态生成序号12345

如何使用JavaScript实现无缝滚动自动播放轮播图效果

页面有多少li(图片),就有多少序号

2. 点击序号、显示高亮、切换图片

2.1 给序号注册onclick事件

2.2 取消其他序号高亮显示,让当前点击的序号高亮显示

2.3 点击序号,动画的方式切换到当前点击的图片位置(设置自定义属性,记录当前索引,有了索引就可用动画进行移动)

如何使用JavaScript实现无缝滚动自动播放轮播图效果

3. 鼠标放到盒子上的时候显示左右箭头,移开时候隐藏

onmouseenter和onmouseleave

如何使用JavaScript实现无缝滚动自动播放轮播图效果

4. 实现左右箭头播放上一张下一张(无缝滚动)

如何使用JavaScript实现无缝滚动自动播放轮播图效果

5. 隔多少时间自动播放

setIntervalelement1..click() 联合即可实现

代码: index.html:

<!DOCTYPE html>
<html lang="en">

  <head>
    <meta charset="UTF-8">
    <title></title>
    <style type="text/css">
      * {
        padding: 0;
        margin: 0;
        list-style: none;
        border: 0;
      }

      body {
        margin: 0;
        background-color: rgb(55, 190, 89);
      }

      .all {
        width: 500px;
        height: 200px;
        padding: 4px;
        margin: 100px auto;
        position: relative;
        background-color: #fff;
        border-radius: 20px;
      }

      .screen {
        width: 500px;
        height: 200px;
        border-radius: 17px;
        overflow: hidden;
        position: relative;
      }

      .screen li {
        width: 500px;
        height: 200px;
        overflow: hidden;
        float: left;
      }

      .screen ul {
        position: absolute;
        left: 0;
        top: 0px;
        width: 3000px;
      }

      .all ol {
        position: absolute;
        right: 180px;
        bottom: 10px;
        line-height: 20px;
        text-align: center;
      }
      
      .all ol li {
        float: left;
        width: 20px;
        height: 20px;
        background: #fff;
        border-radius: 10px;
        border: 1px solid #ccc;
        margin-left: 10px;
        cursor: pointer;
        opacity: 0.5;
        /* 透明度 */
      }

      .all ol li.current {
        opacity: 1.0;
      }

      #arr {
        display: none;
        z-index: 1000;

      }

      #arr span {
        width: 40px;
        height: 40px;
        position: absolute;
        left: 5px;
        top: 50%;
        margin-top: -20px;
        background: #000;
        cursor: pointer;
        line-height: 40px;
        text-align: center;
        font-weight: bold;
        font-family: '黑体';
        font-size: 30px;
        color: #fff;
        opacity: 0.5;
        border: 1px solid #fff;
        border-radius: 5px;
      }

      #arr #right {
        right: 5px;
        left: auto;
      }
    </style>
  </head>

  <body>
    <div class="all" id='box'>
      <div class="screen">
        <ul>
          <li><img src="images/wf1.jpg" width="500" height="200" /></li>
          <li><img src="images/wf2.jpg" width="500" height="200" /></li>
          <li><img src="images/wf3.jpg" width="500" height="200" /></li>
          <li><img src="images/wf4.jpg" width="500" height="200" /></li>
          <li><img src="images/wf5.jpg" width="500" height="200" /></li>
        </ul>
        <ol>
        </ol>
      </div>
      <div id="arr"><span id="left"><</span><span id="right">></span></div>
    </div>
    <script src="common.js"></script>
    <script src="animate.js"></script>
    <script src="index.js"></script>
  </body>

</html>

index.js

//获取元素
var box = my$('box');
var screen = box.children[0];
var ul = screen.children[0];
var ol = screen.children[1]
//获取箭头
var arr = my$('arr');
var arrLeft = my$('left');
var arrRight = my$('right');
var count = ul.children.length; /* 获取图片数量 还没有放cloneLi,所以数值是5*/
var imgWidth = screen.offsetWidth; /* 获取的图片(盒子)的宽高 */
//1.动态生成序号
for (i = 0; i < count; i++) {
  // 在ol内创建li
  var li = document.createElement('li');
  ol.appendChild(li);
  // li内赋予数值
  setInnerText(li, i + 1);
  li.onclick = liClick;
  // 设置标签的自定义属性(创建索引)
  li.setAttribute('index', i);
}

// 2.点击序号,切换,显示高亮
function liClick() {
  // 取消其他的li的高亮,显示当前li高亮
  for (i = 0; i < ol.children.length; i++) {
    var li = ol.children[i];
    li.className = '';
    this.className = 'current';
  }

  // 获取的自定义属性是字符串类型,要转成整数
  var liIndex = parseInt(this.getAttribute('index'));
  animate(ul, -liIndex * imgWidth);
  //使得后面定义的全局变量index等于li的属性liIndex
  index = liIndex;
}

//ol内的第一个li显示高亮色
ol.children[0].className = 'current';

//3.鼠标放上去的时候显示箭头
// onmouseover和onmouseout会触发事件冒泡;onmouseleave和onmouseenter不会触发事件冒泡
box.onmouseenter = function () {
  arr.style.display = 'block';
  clearInterval(timeId);
}

box.onmouseleave = function () {
  arr.style.display = 'none';
  timeId = setInterval(function () {
    arrRight.click();
  }, 2500)
}

// 4.实现上一张,下一张的功能  
var index = 0; //第一张图片的索引

arrRight.onclick = function () {
  // 判断是否是克隆的第一张图片,如果是克隆的第一张图片,此时修改ul的坐标,显示真正的第一张图片
  if (index === count) {
    ul.style.left = '0px';
    index = 0;
  }


  // 如果是最后一张图片,不让index++
  index++;
  // 有5张图片,但是还有一张克隆的图片,克隆图片索引是5
  if (index < count) {
    //获取图片对应的序号,让序号进行点击
    ol.children[index].click();
  } else {
    animate(ul, -index * imgWidth);
    // 取消所有的高亮现实,让第一个序号高亮显示
    for (var i = 0; i < ol.children.length; i++) {
      var li = ol.children[i];
      li.className = '';
    }
    ol.children[0].className = 'current';
  }

  // 
}

arrLeft.onclick = function () {
  if (index === 0) {
    index = count;
    ul.style.left = -index * imgWidth + 'px';
  }
  index--;
  ol.children[index].click();
}

// 无缝滚动
var firstLi = ul.children[0];
// 克隆li  
//cloneNode() 复制节点:参数 true 复制节点中的内容 ;false 只复制当前节点,不复制里面的内容
var cloneLi = firstLi.cloneNode(true);
ul.appendChild(cloneLi)


// 5.自动播放
var timeId = setInterval(function () {
  // 切换到下一张图片
  arrRight.click();
}, 2500)

common.js

function my$(id) {
  return document.getElementById(id);
 }
 
 // 处理浏览器兼容性
 // 获取第一个子元素
 function getFirstElementChild(element) {
   var node, nodes = element.childNodes, i = 0;
   while (node = nodes[i++]) {
     if (node.nodeType === 1) {
       return node;
     }
   }
   return null;
 }
 
 // 处理浏览器兼容性
 // 获取下一个兄弟元素
  function getNextElementSibling(element) {
   var el = element;
   while (el = el.nextSibling) {
    if (el.nodeType === 1) {
      return el;
    }
   }
   return null;
  }
 
 
 // 处理innerText和textContent的兼容性问题
 // 设置标签之间的内容
 function setInnerText(element, content) {
  // 判断当前浏览器是否支持 innerText
  if (typeof element.innerText === 'string') {
   element.innerText = content;
  } else {
   element.textContent = content;
  }
 }
 
 // 处理注册事件的兼容性问题
 // eventName, 不带on, click mouseover mouseout
 function addEventListener(element, eventName, fn) {
  // 判断当前浏览器是否支持addEventListener 方法
  if (element.addEventListener) {
   element.addEventListener(eventName, fn); // 第三个参数 默认是false
  } else if (element.attachEvent) {
   element.attachEvent('on' + eventName, fn);
  } else {
   // 相当于 element.onclick = fn;
   element['on' + eventName] = fn;
  }
 }
 
 // 处理移除事件的兼容性处理
 function removeEventListener(element, eventName, fn) {
  if (element.removeEventListener) {
   element.removeEventListener(eventName, fn);
  } else if (element.detachEvent) {
   element.detachEvent('on' + eventName, fn);
  } else {
   element['on' + eventName] = null;
  }
 }
 
 // 获取页面滚动距离的浏览器兼容性问题
 // 获取页面滚动出去的距离
 function getScroll() {
  var scrollLeft = document.body.scrollLeft || document.documentElement.scrollLeft;
  var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
  return {
   scrollLeft: scrollLeft,
   scrollTop: scrollTop
  }
 }
 
 // 获取鼠标在页面的位置,处理浏览器兼容性
 function getPage(e) {
  var pageX = e.pageX || e.clientX + getScroll().scrollLeft;
  var pageY = e.pageY || e.clientY + getScroll().scrollTop;
  return {
   pageX: pageX,
   pageY: pageY
  }
 }
 
 
 //格式化日期对象,返回yyyy-MM-dd HH:mm:ss的形式
 function formatDate(date) {
  // 判断参数date是否是日期对象
  // instanceof instance 实例(对象)  of 的
  // console.log(date instanceof Date);
  if (!(date instanceof Date)) {
   console.error('date不是日期对象')
   return;
  }
 
  var year = date.getFullYear(),
    month = date.getMonth() + 1,
    day = date.getDate(),
    hour = date.getHours(),
    minute = date.getMinutes(),
    second = date.getSeconds();
 
  month = month < 10 ? '0' + month : month;
  day = day < 10 ? '0' + day : day;
  hour = hour < 10 ? '0' + hour : hour;
  minute = minute < 10 ? '0' + minute : minute;
  second = second < 10 ? '0' + second : second;
 
  return year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second;
 }
 
 // 获取两个日期的时间差
 function getInterval(start, end) {
  // 两个日期对象,相差的毫秒数
  var interval = end - start;
  // 求 相差的天数/小时数/分钟数/秒数
  var day, hour, minute, second;
 
  // 两个日期对象,相差的秒数
  // interval = interval / 1000;
  interval /= 1000;
 
  day = Math.round(interval / 60 / 60 / 24);
  hour = Math.round(interval / 60 / 60 % 24);
  minute = Math.round(interval / 60 % 60);
  second = Math.round(interval % 60);
 
  return {
   day: day,
   hour: hour,
   minute: minute,
   second: second
  }
 }

animage.js

// var timerId = null;
// 封装动画的函数
function animate(element, target) {
  // 通过判断,保证页面上只有一个定时器在执行动画
  if (element.timerId) {
   clearInterval(element.timerId);
   element.timerId = null;
  }
 
  element.timerId = setInterval(function () {
   // 步进 每次移动的距离
   var step = 10;
   // 盒子当前的位置
   var current = element.offsetLeft;
   // 当从400 到 800 执行动画
   // 当从800 到 400 不执行动画
 
   // 判断如果当前位置 > 目标位置 此时的step 要小于0
   if (current > target) {
    step = - Math.abs(step);
   }
 
   // Math.abs(current - target)  <= Math.abs(step)
   if (Math.abs(current - target)  <= Math.abs(step)) {
    // 让定时器停止
    clearInterval(element.timerId);
    // 让盒子到target的位置
    element.style.left = target + 'px';
    return;
   }
   // 移动盒子
   current += step;
   element.style.left = current + 'px';
  }, 5);
 }

总结

到此这篇关于如何使用JavaScript实现无缝滚动自动播放轮播图效果的文章就介绍到这了,更多相关js无缝滚动自动播放内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
jquery入门—数据删除与隔行变色以及图片预览
Jan 07 Javascript
jQuery Ajax异步处理Json数据详解
Nov 05 Javascript
10个很棒的jQuery代码片段
Sep 24 Javascript
js获取及判断键盘按键的方法
Dec 01 Javascript
jQuery获取某天的农历日期并判断是否除夕或新年的方法
Mar 01 Javascript
深入研究jQuery图片懒加载 lazyload.js使用方法
Aug 16 jQuery
JavaScript基于面向对象实现的猜拳游戏
Jan 03 Javascript
Node.js使用Koa搭建 基础项目
Jan 08 Javascript
JavaScript根据json生成html表格的示例代码
Oct 24 Javascript
JavaScript数组去重的方法总结【12种方法,号称史上最全】
Feb 28 Javascript
Vue toFixed保留两位小数的3种方式
Oct 23 Javascript
如何利用JavaScript实现二叉搜索树
Apr 02 Javascript
JavaScript 空间坐标的使用
Aug 19 #Javascript
vue插件--仿微信小程序showModel实现模态提示窗功能
Aug 19 #Javascript
jQuery实现评论模块
Aug 19 #jQuery
javaScript代码飘红报错看不懂?读完这篇文章再试试
Aug 19 #Javascript
jQuery实现简单评论功能
Aug 19 #jQuery
原生JS实现多条件筛选
Aug 19 #Javascript
微信小程序wx.getUserInfo授权获取用户信息(头像、昵称)的实现
Aug 19 #Javascript
You might like
PHP函数utf8转gb2312编码
2006/12/21 PHP
PHP 网络开发详解之远程文件包含漏洞
2010/04/25 PHP
对于ThinkPHP框架早期版本的一个SQL注入漏洞详细分析
2014/07/04 PHP
PHP常用设计模式之委托设计模式
2016/02/13 PHP
人脸识别测颜值、测脸龄、测相似度微信接口
2016/04/07 PHP
JavaScript中setFullYear()方法的使用详解
2015/06/11 Javascript
Jquery实现弹性滑块滑动选择数值插件
2015/08/08 Javascript
require.js配合插件text.js实现最简单的单页应用程序
2016/07/12 Javascript
微信小程序 用户数据解密详细介绍
2017/01/09 Javascript
jquery实现异步加载图片(懒加载图片一种方式)
2017/04/24 jQuery
Node.js+ELK日志规范的实现
2019/05/23 Javascript
通过Nodejs搭建网站简单实现注册登录流程
2019/06/14 NodeJs
浅析Vue中拆分视图层代码的5点建议
2019/08/15 Javascript
layui文件上传控件带更改后数据传值的方法
2019/09/23 Javascript
js实现小时钟效果
2020/03/25 Javascript
[01:18:43]2014 DOTA2华西杯精英邀请赛5 24 iG VS DK
2014/05/25 DOTA
[10:18]2018DOTA2国际邀请赛寻真——找回自信的TNCPredator
2018/08/13 DOTA
用Python制作简单的朴素基数估计器的教程
2015/04/01 Python
Django实现组合搜索的方法示例
2018/01/23 Python
python读取多层嵌套文件夹中的文件实例
2020/02/27 Python
Python函数参数定义及传递方式解析
2020/06/10 Python
在keras中model.fit_generator()和model.fit()的区别说明
2020/06/17 Python
Python os库常用操作代码汇总
2020/11/03 Python
全球知名提供各类营养保健品的零售商:Vitamin Shoppe
2016/10/09 全球购物
TUMI新加坡官网:国际领先的商旅箱包品牌
2019/01/12 全球购物
Hawes & Curtis官网:英国经典品牌
2019/07/27 全球购物
华三通信H3C面试题
2015/05/15 面试题
外贸主管求职简历的自我评价
2013/10/23 职场文书
护理人员的自我评价分享
2014/03/15 职场文书
给孩子的新年寄语
2014/04/08 职场文书
2014第二批党员干部对照“四风”找差距检查材料思想汇报
2014/09/18 职场文书
食品卫生管理制度
2015/08/06 职场文书
远程教育培训心得体会
2016/01/09 职场文书
2019年12月24日平安夜祝福语集锦
2019/12/24 职场文书
Java详细解析==和equals的区别
2022/04/07 Java/Android
索尼ICF-36收音机评测
2022/04/30 无线电