原生js封装无缝轮播功能

原生js封装无缝轮播插件,供大家参考,具体内容如下

说明:

这是一个使用原生js、es5语法写出的无缝轮播程序,代码中对相关api进行了封装,使得在引入该轮播js文件后,只需要在自己的js文件中添加两行代码即可在网页中实现一个基本的无缝轮播图效果。

基本使用步骤为:获取dom元素数组、向轮播对象中传参、轮播对象调用自动轮播方法。

除基本的定时器自动轮播功能外,该程序还支持设置过渡动画时间、设置鼠标移入元素自动轮播停止、设置点击左右侧边按钮时轮播、设置点击下方按钮时轮播功能。

该程序不需要依赖css、html文件、但需要你的css、html布局遵循一定的规则。

注意该程序不支持曲线过渡速度、且在将浏览器切换浏览器窗口后有时会出现轮播图错乱的bug,暂时找不到问题的所在。

该程序仅是我一个初学者对无缝轮播函数的简单封装,仅能够做学习和参考使用。

下面除轮播代码外,我还会给出示例程序。

运行效果:

思路:

根据轮播的方向确定所有轮播图元素的排列顺序,如果当前轮播图已到达所有轮播图的边界,则将相对方向上的最后一张轮播图瞬间移动到相应位置。
使用这种方法实现轮播图所需要的最少轮播图数为3张,针对轮播图数量为一张和两张的情况则需要对其单独处理,一张情况下,复制添加两张和当前轮播图相同的轮播图元素,两张情况下,需要按顺序对当前轮播图进行复制添加。

编译环境:

Chrome 86.0.4240.183

代码:

slide.js 封装轮播图代码

(function(window, undefined) {

 // 获取元素css属性值
 function getCss(elem, attr) {
  return elem.currentStyle ?
   elem.currentStyle[attr] :
   window.getComputedStyle(elem, null)[attr];
 }

 // 去除字符串中的非数字,不包括负号
 function toInt(str) {
  var rex = /[^0-9]/ig;
  return Number((str[0] === '-' && str[1] !== '=') ? '-' + str.replace(rex, '') : str.replace(rex, ''));
 }

 // 封装动画函数,参数:dom对象、css属性值对象、动画执行时间、动画完成后回调
 function animation(elem, params, speed, callback) {
  for (var param in params) {
   (function(param) {

    var elemValue = toInt(getCss(elem, param)),
     targetValue = toInt(params[param]),
     currentDis = elemValue,
     unit = params[param].substr(params[param].indexOf('[A-Za-z]+') - 1);

    if (params[param].length > 2) {
     var prefix = params[param].substr(0, 2);

     if (prefix === '+=')
      targetValue = elemValue + targetValue;
     else if (prefix === '-=')
      targetValue = elemValue - targetValue;
    }

    var dis = (targetValue - elemValue) / speed,
     sizeFlag = targetValue < elemValue;

    var timer = setInterval(function() {

     elemValue = toInt(getCss(elem, param));

     if (sizeFlag) {
      if (currentDis <= targetValue) {
       clearInterval(timer);
       elem.style[param] = targetValue + unit;
      } else {
       currentDis += dis;
       elem.style[param] = currentDis + unit;
      }
     }
     else {
      if (currentDis >= targetValue) {
       clearInterval(timer);
       elem.style[param] = targetValue + unit;
      } else {
       currentDis += dis;
       elem.style[param] = currentDis + unit;
      }
     }
    }, 1);

   })(param);
  }

  if (typeof callback === 'function')
   callback();
 };

 // 向右轮播数组移动
 function rightRoundArrayMove() {

  var winsLen = wins.length;
  var lastWin = wins[winsLen - 1];

  for (var i = winsLen - 1; i > 0; i--)
   wins[i] = wins[i - 1];

  wins[0] = lastWin;
 }

 // 向左轮播
 function rightRound(time) {

  rightRoundArrayMove();

  wins.forEach(function(win, index) {
   (index === 0) ?
    win.style.left = index * winWidth - winWidth + 'px' :
    animation(win, {left: '+=' + winWidth + 'px'}, time ? time : animationTime);
  });
 }

 // 向右轮播
 function leftRound(time) {

  var winsLen = wins.length;
  var firstWin = wins[0];

  for (var i = 0; i < winsLen - 1; i++)
   wins[i] = wins[i + 1];

  wins[winsLen - 1] = firstWin;

  wins.forEach(function(win, index) {
   (index === wins.length - 1) ?
    win.style.left = index * winWidth - winWidth + 'px' :
    animation(win, {left: '-=' + winWidth + 'px'}, time ? time : animationTime);
  });
 }

 var
  // wins, btns, sbtns用于保存构造函数的参数
  wins,
  btns,
  sbtns,
  // 窗口的宽度
  winWidth,
  // 过渡动画时间(毫秒),默认为100
  animationTime = 100,
  // 点击按钮轮播间隔
  clickInterval = animationTime << 2,
  // 保存自动轮播定时器、定时器间隔、是否向右轮播
  autoRoundTimer,
  qinterval,
  qisRight,
  // slide构造函数,参数:窗口数组,按钮数组,侧边按钮数组
  slide = function(wins, btns, sbtns) {
   return new slide.prototype.init(wins, btns, sbtns);
  };

 slide.prototype = {

  // 初始化窗口元素
  init: function(awins, abtns, asbtns) {

   if (!awins)
    throw new Error('The window array cannot be empty.');

   wins = Object.values(awins), btns = abtns, sbtns = asbtns;

   // 处理窗口少于3个的情况
   if (wins.length === 1) {
    var winParent = wins[0].parentNode;
    var winHTML = wins[0].outerHTML;
    winParent.innerHTML += winHTML + winHTML;
    wins = Object.values(winParent.children);
   }
   else if (wins.length === 2) {
    var winParent = wins[0].parentNode;
    winParent.innerHTML += wins[0].outerHTML + wins[1].outerHTML;
    wins = Object.values(winParent.children);
   }

   winWidth = wins[0].offsetWidth;

   wins.forEach(function(win, index) {
    win.style.position = 'absolute';
    win.index = index;
   });

   rightRoundArrayMove();

   wins.forEach(function(win, index) {
    win.style.left = index * winWidth - winWidth + 'px';
   });
  },

  // 设置过渡动画时间
  setAnimationTime: function(time) {
   animationTime = time;
   clickInterval = animationTime << 2;
  },

  // 自动轮播,参数:轮播时间间隔、是否为向右轮播
  autoRound: function(interval, isRight) {
   autoRoundTimer = setInterval(function() {
        isRight ? rightRound() : leftRound();
       }, interval);
   qinterval = interval;
   qisRight = isRight;
  },

  // 侧边按钮点击,参数为侧边按钮元素数组,该参数可在构造函数中传递或现在传递
  sideBtnClickRound: function(sabtns) {

   var leftBtn = sabtns ? sabtns[0] : sbtns[0],
    rightBtn = sabtns ? sabtns[1] : sbtns[1];

   var isclick= true;
   leftBtn.onclick = function () {
    if(isclick) {
     isclick= false;
     rightRound();
     setTimeout(function() {
      isclick = true;
     }, clickInterval);
    }
   };

   rightBtn.onclick = function () {
    if(isclick) {
     isclick= false;
     leftRound();
     setTimeout(function() {
      isclick = true;
     }, clickInterval);
    }
   };
  },

  // 普通按钮点击,参数:普通按钮数组、回调
  btnsClickRound: function(abtns, callback) {

   var ibtns = abtns ? abtns : btns;

   var isclick= true;

   ibtns.forEach(function(btn, index) {
    btn.onclick = function() {
     if(isclick) {
      isclick= false;

      if (typeof callback === 'function')
       callback(ibtns, btn, index);

      var poor = index - wins[1].index;
      var count = Math.abs(poor);
      if (poor < 0) {
       var absPoor = count;
       var timer = setInterval(function() {
        console.log((absPoor + 1))
           rightRound(animationTime / (absPoor + 2));
           if ((--count) === 0)
            clearInterval(timer);
          }, animationTime);
      }
      else if (poor > 0) {
       var timer = setInterval(function() {
           leftRound(animationTime / (poor + 2));
           if ((--count) === 0)
            clearInterval(timer);
          }, animationTime);
      }

      setTimeout(function() {
       isclick = true;
      }, clickInterval << 1);
     }
    }
   });
  },

  // 设置鼠标移入取消自动轮播,参数:移入的元素、移入元素回调、移出元素回调
  setOverStop: function(box, overCallback, outCallback) {
   box.onmouseover = function(e) {
    clearInterval(autoRoundTimer);

    if (typeof overCallback === 'function')
     overCallback(e);
   }
   box.onmouseout = function(e) {
    slide.prototype.autoRound(qinterval, qisRight);

    if (typeof outCallback === 'function')
     outCallback(e);
   }
  }
 }

 slide.prototype.init.prototype = slide.prototype;
 window.slide = _slide = slide;

})(window);

test.js 测试示例js代码:

onload = function() {

 var wins = document.querySelectorAll('.wins > li');
 var btns = document.querySelectorAll('.btns > li');
 var sideBtns = document.querySelectorAll('.side-btns > div');
 var box = document.querySelector('.box');

 var s = slide(wins, btns, sideBtns); // 创建轮播对象,参数:窗口dom数组、下方按钮dom数组(可选)、
 s.autoRound(2000);   // 设置自动轮播
 s.setAnimationTime(200); // 设置过渡动画时间
 s.setOverStop(box);   // 设置鼠标移入元素时自动轮播停止,参数:移入的dom元素、移入元素回调、移出元素回调
 s.sideBtnClickRound();  // 设置点击侧边按钮时轮播,参数:按钮dom数组(可选)
 s.btnsClickRound();   // 设置下方按钮点击时轮播,参数:按钮dom数组(可选)、回调
}

html、css示例代码

<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8" />
  <title></title>
  <style type="text/css">
   * {
    margin: 0;
    padding: 0;
   }

   li {
    list-style: none;
   }

   .box {
    width: 1000px;
    height: 400px;
    margin: 20px auto;
    display: flex;
    align-items: center;
    position: relative;
    overflow: hidden;
   }

   .box > * {
    position: absolute;
   }

   .side-btns {
    width: inherit;
    height: 100px;
    display: flex;
    justify-content: space-between;
    z-index: 2;
   }

   .side-btns > div {
    width: 50px;
    height: inherit;
    text-align: center;
    line-height: 100px;
    font-size: 18px;
    background-color: rgba(0, 0, 0, .3);
    color: white;
    cursor: pointer;
    user-select: none;
   }

   .btns {
    width: inherit;
    height: 20px;
    display: flex;
    justify-content: flex-end;
    z-index: 2;
    position: absolute;
    bottom: 20px;
   }

   .btns > li {
    width: 16px;
    height: 16px;
    border-radius: 50%;
    margin-right: 12px;
    cursor: pointer;
    background-color: rgba(0, 0, 0, .2);
   }

   .wins {
    width: inherit;
    height: inherit;
    display: flex;
   }

   .wins > li {
    width: inherit;
    height: inherit;
    flex-grow:0;
    flex-shrink:0;
   }
  </style>
  <script src="js/slide.js"></script>
  <script src="js/test.js"></script>
 </head>

 <body>
  <div class="box">
   <div class="side-btns">
    <div class="left-btn">&lt;</div>
    <div class="right-btn">&gt;</div>
   </div>

   <ul class="btns">
    <li></li>
    <li></li>
    <li></li>
    <li></li>
   </ul>

   <ul class="wins">
    <li style="background-color: antiquewhite;">a</li>
    <li style="background-color: aquamarine;">b</li>
    <li style="background-color: green;">c</li>
    <li style="background-color: brown;">d</li>
   </ul>
  </div>
 </body>
</html>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • js实现无缝轮播图特效

    用原生js实现无缝轮播图,供大家参考,具体内容如下 index.js: var config = { imgWidth:380,//图片尺寸 dotWidth:8,//小圆点尺寸 doms:{ divImgs:document.querySelector('.imgs'), divDots:document.querySelector('.circle'), divDirection:document.querySelector('.direction'), divContainer:docum

  • JS实现左右无缝轮播图代码

    废话不多说了,直接给大家贴代码了. 无缝轮播图: <title>无缝轮播图</title> <style> *{margin: 0;padding:0; } ul{list-style: none;} .banner{width: 600px;height: 300px;border: 2px solid #ccc;margin: 100px auto;position: relative;overflow: hidden;} .img{position: absolu

  • 原生js实现无缝轮播图效果

    话不多说,请看代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>无缝轮播图-原生js封装</title> <link rel="shortcut icon" href="../public/image/favicon.ico" type="ima

  • JS实现动态无缝轮播

    在同学的帮助下,终于使用纯js代码实现了动态轮播,学无止境加油吧! 效果图是这样的,我们需要定义一个div,并放入三张图片,还需要左右两个按钮,以及底下三个按钮三个div. 先看布局代码 <div class="banner" id="banner"> <ul class="clear" > <li style="left:0" ><img src="k1.jpg"

  • 原生js无缝轮播插件使用详解

    这篇博文主要讲如何使用原生js来实现一个兼容 IE9+ 的无缝轮播图.主要知识点如下: 面向对象 js优化之节流函数 js运动 效果 html结构 <div class="sliders-wraper" id="rotation-1"> <ul class="sliders clear"> <li class="slider" style="background:purple"

  • 原生js实现无缝轮播图

    本文实例为大家分享了js实现无缝轮播图的具体代码,供大家参考,具体内容如下 先上效果图 原理图 如图可见,是页面按顺序依次显示5张图片,包裹这五张图片的外层的盒子,我们叫ul,通过向左或右移动不同距离,实现在视图中显示的不同的图片,实现轮播,而同时下面的分页小球需要根据当前显示的内容进行点亮: 而无缝轮播图需要在第五张图片后面再加上第一张图片,这样通过右侧箭头,向右切换,当页面切换到第六张时,也就是最后一张图片,此时需要将ul的位置设置为第一张图的位置,然后从第一张图片滑动到第二张,形成一个无缝

  • JS左右无缝轮播功能完整实例

    本文实例讲述了JS左右无缝轮播功能.分享给大家供大家参考,具体如下: 其中对上一页下一页按钮设置visibility属性是为了解决轮播中点击上一页下一页导致的bug,应为是a标签所以用了visibility属性,如果是按钮button可以直接设置在轮播过程中按钮不可点击,当然其他解决方法都可以,以实际为准 代码如下:换换图片就可以直接用 <!DOCTYPE html> <html> <head lang="en"> <meta charset=

  • js实现无缝轮播图

    本文实例为大家分享了js实现轮播图的具体代码,供大家参考,具体内容如下 CSS样式: <style type="text/css"> #box{width: 1000px;height: 375px;border: 3px solid black; margin: 30px auto;position: relative;overflow: hidden;} #box .img{position: absolute;left: 0;top: 0;} #box .img im

  • js实现无缝轮播图效果

    本文实例为大家分享了js实现无缝轮播图的具体代码,供大家参考,具体内容如下 //Utils.js //封装 预加载图片 var Utils=(function () { return { //SSS loadImg:function (srcList,callBack) {//图片地址 回调函数 var img=new Image(); img.num=0;//初始化num为0 图片数 img.imgList=[];//存放图片 img.srcList=srcList; img.callBack

  • js实现从右往左匀速显示图片(无缝轮播)

    本文实例为大家分享了js实现从右往左匀速显示图片的具体代码,供大家参考,具体内容如下 前言: 匀速显示图片,一般用于重复显示公司活动系列图片 背景图片: <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <style type="text/css"> *{ margin: 0; padding: 0; } .

随机推荐