如何使用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 相关文章推荐
javascript 混合的构造函数和原型方式,动态原型方式
Dec 07 Javascript
使用indexOf等在JavaScript的数组中进行元素查找和替换
Sep 18 Javascript
getAsDataURL在Firefox7.0下无法预览本地图片的解决方法
Nov 15 Javascript
jQuery插件jRumble实现网页元素抖动
Jun 05 Javascript
jQuery实现商品活动倒计时
Oct 16 Javascript
Bootstrap基本插件学习笔记之标签切换(17)
Dec 08 Javascript
Vue表单验证插件的制作过程
Apr 01 Javascript
使用vue的v-for生成table并给table加上序号的实例代码
Oct 27 Javascript
解决vue动态为数据添加新属性遇到的问题
Sep 18 Javascript
使用 Github Actions 自动部署 Angular 应用到 Github Pages的方法
Jul 20 Javascript
vue+elementUI(el-upload)图片压缩,默认同比例压缩操作
Aug 10 Javascript
vue项目实现多语言切换的思路
Sep 17 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之第十天
2006/10/09 PHP
Zend Framework教程之Zend_Form组件实现表单提交并显示错误提示的方法
2016/03/21 PHP
PHP Socket网络操作类定义与用法示例
2017/08/30 PHP
利用php获得flv视频长度的实例代码
2017/10/26 PHP
详细解读php的命名空间(一)
2018/02/21 PHP
php设计模式之建造器模式分析【星际争霸游戏案例】
2020/01/23 PHP
使用Entrust扩展包在laravel 中实现RBAC的功能
2020/03/16 PHP
用prototype实现的简单小巧的多级联动菜单
2007/03/24 Javascript
网页和浏览器兼容性问题汇总(draft1)
2009/06/01 Javascript
JavaScript 数组循环引起的思考
2010/01/01 Javascript
浅析document.createDocumentFragment()与js效率
2013/07/08 Javascript
Extjs Label的 fieldLabel和html属性值对齐的方法
2014/06/15 Javascript
深入理解javascript作用域和闭包
2014/09/23 Javascript
浅谈JavaScript 框架分类
2014/11/10 Javascript
Linux下编译安装php libevent扩展实例
2015/02/14 Javascript
关于javascript原型的修改与重写(覆盖)差别详解
2016/08/31 Javascript
JS使用setInterval实现的简单计时器功能示例
2018/04/19 Javascript
详解Element 指令clickoutside源码分析
2019/02/15 Javascript
vue.js使用v-model实现父子组件间的双向通信示例
2020/02/05 Javascript
vue界面发送表情的实现代码
2020/09/11 Javascript
python代码检查工具pylint 让你的python更规范
2012/09/05 Python
跟老齐学Python之模块的加载
2014/10/24 Python
Python中使用第三方库xlrd来写入Excel文件示例
2015/04/05 Python
Python使用matplotlib模块绘制图像并设置标题与坐标轴等信息示例
2018/05/04 Python
Python使用pickle模块报错EOFError Ran out of input的解决方法
2018/08/16 Python
Python找出微信上删除你好友的人脚本写法
2018/11/01 Python
Python动态参数/命名空间/函数嵌套/global和nonlocal
2019/05/29 Python
Python3 执行系统命令并获取实时回显功能
2019/07/09 Python
python中用logging实现日志滚动和过期日志删除功能
2019/08/20 Python
Python中的延迟绑定原理详解
2019/10/11 Python
python设置代理和添加镜像源的方法
2020/02/14 Python
python3的pip路径在哪
2020/06/23 Python
环境科学专业个人求职信
2013/12/15 职场文书
街道社区活动报告
2015/02/05 职场文书
纯 CSS 自定义多行省略的问题(从原理到实现)
2021/11/11 HTML / CSS
win10双系统怎么删除一个系统?win10电脑有两个系统删除一个的操作方法
2022/07/15 数码科技