JavaScript实现移动端带transition动画的轮播效果


Posted in Javascript onMarch 24, 2020

JavaScript实现轮播的方式多种多样,桌面的移动端的实现方式都是大同小异的,具体的核心实现原理不外乎下面几个要点。即:

1. 确定播放方向。一般都是横向轮播,当然不排除纵向的需求可能。当然还有反向播放情况,这个自定义。
2. 对第一张图片的处理。如果当前是第一张了,那么如果继续往前面(就是你播放方向的反向)滑动,那么就会出现留白(如果你允许继续滑动的话,不过不允许滑动也没有啥意思了,除非你想来回轮播,这个我在另一篇用jQuery也说明过),此时应该让你的左边显示应该轮播图片的最后一张,实现无缝连接。
3. 对最后一张图片的处理。跟第一张一样,你需要在继续滑动的时候显示第一张图片,实现无缝连接。
4. 对标记跟随原点的处理。这个需要对原点的排列方式和下标进行严谨的逻辑判断。

我这里是在移动端的一个轮播效果,纯JavaScript原生实现,应该说很接近工作实际了。请诸位爷上眼。

注意:如果您想实现跟我一样的效果,请务必按我的样式和架构来写

HTML部分

<div id="box">
 <ul id="lilist">
 <li><img src="5.jpg" alt=""></li>
 <li><img src="1.jpg" alt=""></li>
 <li><img src="2.jpg" alt=""></li>
 <li><img src="3.jpg" alt=""></li>
 <li><img src="4.jpg" alt=""></li>
 <li><img src="5.jpg" alt=""></li>
 <li><img src="1.jpg" alt=""></li>
 </ul>
 <ul id="items">
 <li class="active"></li>
 <li></li>
 <li></li>
 <li></li>
 <li></li>
 </ul>
</div>

CSS部分

*{ margin: 0;padding: 0; }
 html,body{ height: 100%;}
 #box{
  width: 100%;
  overflow: hidden;
  position: relative;
 }
 #box #lilist{
  /* 宽度根据子元素个数动态确定 */
  /*width: 500%;*/
  position: relative;
  float: left;
  white-space: nowrap;
  list-style: none;
  overflow: hidden;
 }
 #box #lilist li{
  float: left;
  height: 200px;
 }
 #box #lilist li img{
  display: block;
  width: 100%;
  height: 100%;
  object-fit: fill;
 }

 #box #items{
  position: absolute;
  list-style: none;
  width: 30%;
  bottom: 10px;
  left: 35%;
  display: flex;
  flex-flow: row nowrap;
  justify-content: space-between;
 }
 #box #items li{
  float: left;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background-color: black;
 }
 #box #items .active{
  background-color: red;
 }

重点来啦,JavaScript原生代码:

window.onload = function(){
var totalli1 = document.querySelectorAll("#box>#lilist>li");
 var totalli2 = document.querySelectorAll("#box>#items>li");

 // 动态改变轮播图宽度
 changewidth();
 function changewidth(){
 var newstyle = document.createElement("style");
 var mycss = "#lilist{ width : "+totalli1.length+"00% }";
  mycss += "#lilist li{ width : "+(100/totalli1.length)+"% }"
 newstyle.innerHTML = mycss;
 document.head.appendChild(newstyle);
 }

 var getbox = document.getElementById("box");
 var getlist = document.getElementById("lilist");
 var startx = 0, endx = 0, disx = 0;
 var listleft = 0, finalx = 0;
 var windowx = document.documentElement.offsetWidth;
 var listx = getlist.offsetWidth;
 var moveindex = 0;
 // 自动轮播控制变量
 var num = 1, index = 0;
 // 先让他左滑
 transforms(getlist,"translateX",-windowx);

 getbox.addEventListener("touchstart",function(event){
 let touch = event.changedTouches[0];
 startx = touch.clientX;
 // 首位位置判断,并重新定位.鼠标刚放上去就要改变位置,不然move移动再改的话会和移动的transform冲突,也不能在鼠标离开时切换,会影响到移动的滑动效果。这个过程中是瞬间完成的,不允许过渡或动画,显得平滑。
 let lastx = Math.round(-transforms(getlist,"translateX")/windowx);
 if(lastx<1){
  lastx = totalli1.length-2;
 }else if(lastx>totalli1.length-2){
  lastx = 1;
 }
 // 移动到指定位置
 transforms(getlist,"translateX",-lastx*windowx);
 // 给 listleft 赋值
 listleft = transforms(getlist,"translateX");
 // 清除过度缓冲
 getlist.style.transition = "none";
 // 清除计时器
 window.clearInterval(timer);
 })
 getbox.addEventListener("touchmove",function(event){
 let touch = event.changedTouches[0];
 endx = touch.clientX;
 disx = endx - startx;
 finalx = disx+listleft;

 transforms(getlist,"translateX",finalx)
 })
 getbox.addEventListener("touchend",function(event){
 let touch = event.changedTouches[0];
 // 滑动的屏宽个数。
 let lastx = 0;
 // ul 距屏幕左侧的距离与屏宽的比例
 lastx = Math.round(-transforms(getlist,"translateX")/windowx);
 if(lastx<=0){
  lastx = 0;
 }else if(lastx>totalli1.length-1){
  lastx = totalli1.length-1;
 }
 transforms(getlist,"translateX",-lastx*windowx);
 getlist.style.transition = "transform 0.3s";
 // 下部红点跟随,获取下标。诸位请注意下面几个数字的含义,4,5,6的意思你们自己思考一下
 moveindex = lastx-1;
 if(lastx==1||lastx==6){
  moveindex = 0;
 }else if(lastx==0||lastx==5){
  moveindex = 4;
 }
 movecircle(moveindex);
 // 重新添加计时器,自动轮播
 timer = window.setInterval(playself,3000);
 // 改变num和index的值,以确定计时器开始位置
 console.log(moveindex+"。。。"+lastx)
 index = moveindex;
 num = lastx;
 })
 // 自动轮播
 var timer = window.setInterval(playself,3000);
 function playself(){
 // 清除过渡残留
 getlist.style.transition = "none";
 if(num==totalli1.length-1){
  transforms(getlist,"translateX",-windowx);
  num = 1;
 }
 // 再添加一个一次性计时器即可分开与 interval 的冲突
 setTimeout(function(){
  transforms(getlist,"translateX",-windowx*(++num));
  getlist.style.transition = "transform 0.5s";
  // 原点跟随移动
  index++;
  if(index==totalli2.length){
  index = 0;
  totalli2[index].classList.add("active");
  }
  movecircle(index);
 },1)
 }
 // 红点移动函数
 function movecircle(getindex){
 for(let i=0;i<totalli2.length;i++){
  totalli2[i].classList.remove("active");
  if(getindex==i){
  totalli2[getindex].classList.add("active");
  }
 }
 }
}

代码还有一些算法部分的瑕疵,本人愚钝,目前只能想到这种方式了,有些变量可能会占用太多内存,希望各位仅作参考,如有大神指出问题所在,万分感谢。最后,诚心感谢有缘人的观看!祝你生活愉快,工作顺利!

总结

到此这篇关于JavaScript实现移动端带transition动画的轮播效果的文章就介绍到这了,更多相关js transition 轮播内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
jquery tools 系列 scrollable(2)
Sep 06 Javascript
qTip2 精致的基于jQuery提示信息插件
Feb 17 Javascript
JavaScript面向对象之Prototypes和继承
Jul 12 Javascript
javascript实现图片切换的幻灯片效果源代码
Dec 12 Javascript
Jquery自定义button按钮的几种方法
Jun 11 Javascript
一个简单的全屏图片上下打开显示网页效果示例
Jul 08 Javascript
node.js中的dns.getServers方法使用说明
Dec 08 Javascript
分享10个原生JavaScript技巧
Apr 20 Javascript
JavaScript中子对象访问父对象的方式详解
Sep 01 Javascript
canvas知识总结
Jan 25 Javascript
js中开关变量使用实例
Feb 24 Javascript
JavaScript实现微信号随机切换代码
Mar 09 Javascript
javascript实现滚动条效果
Mar 24 #Javascript
Webpack中SplitChunksPlugin 配置参数详解
Mar 24 #Javascript
JS实现点星星消除小游戏
Mar 24 #Javascript
js实现小星星游戏
Mar 23 #Javascript
JS Array.from()将伪数组转换成数组的方法示例
Mar 23 #Javascript
Vue+elementUI实现多图片上传与回显功能(含回显后继续上传或删除)
Mar 23 #Javascript
小程序使用分包的示例代码
Mar 23 #Javascript
You might like
php实现的一段简单概率相关代码
2016/05/30 PHP
javascript 点击整页变灰的效果(可做退出效果)。
2008/01/09 Javascript
Jquery css函数用法(判断标签是否拥有某属性)
2011/05/28 Javascript
得到form下的所有的input的js代码
2013/11/07 Javascript
Jquery Uploadify上传带进度条的简单实例
2014/02/12 Javascript
修复bash漏洞的shell脚本分享
2014/12/31 Javascript
js闭包用法实例详解
2016/12/13 Javascript
深究AngularJS如何获取input的焦点(自定义指令)
2017/06/12 Javascript
vue2.x 父组件监听子组件事件并传回信息的方法
2017/07/17 Javascript
javascript算法之二叉搜索树的示例代码
2017/09/12 Javascript
Popup弹出框添加数据实现方法
2017/10/27 Javascript
vue3.0中使用postcss-pxtorem的具体方法
2019/11/20 Javascript
优化Vue中date format的性能详解
2020/01/13 Javascript
JavaScript 监听组合按键思路及代码实现
2020/07/28 Javascript
[52:31]VP vs Serenity 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
pygame学习笔记(3):运动速率、时间、事件、文字
2015/04/15 Python
python安装以及IDE的配置教程
2015/04/29 Python
Python实现的读写json文件功能示例
2018/06/05 Python
浅谈python中str字符串和unicode对象字符串的拼接问题
2018/12/04 Python
python从子线程中获得返回值的方法
2019/01/30 Python
Python集中化管理平台Ansible介绍与YAML简介
2019/06/12 Python
Python利用pandas处理Excel数据的应用详解
2019/06/18 Python
Python 3.8正式发布重要新功能一览
2019/10/17 Python
使用Python paramiko模块利用多线程实现ssh并发执行操作
2019/12/05 Python
Selenium向iframe富文本框输入内容过程图解
2020/04/10 Python
CSS3实现全景图特效示例代码
2018/03/26 HTML / CSS
Myprotein葡萄牙官方网站:英国优质运动营养品牌
2016/09/12 全球购物
Algenist奥杰尼官网:微藻抗衰老护肤品牌
2017/07/15 全球购物
GafasWorld哥伦比亚:网上购买眼镜
2017/11/28 全球购物
团员个人的自我评价
2013/12/02 职场文书
工厂总经理岗位职责
2014/02/07 职场文书
2014年教育培训工作总结
2014/12/08 职场文书
2014年控辍保学工作总结
2014/12/08 职场文书
少年雷锋观后感
2015/06/10 职场文书
2016简历自荐信优秀范文
2016/01/29 职场文书
MySQL Router实现MySQL的读写分离的方法
2021/05/27 MySQL