JS实现某东移动web轮播图

移动web轮播图

参考实例,可以从中保存轮播图的图片,这里我们放入uploads的文件夹下,将八张图片一次改为l1.jpg,l2.jpg…

https://m.jd.com/

HTML

  1. 这里要放入十张图片,因为手指滑动的时候要从第一张滑动到最后一张,是无缝滑动,当然可以用原生的JS进行添加
  2. 最终我们可以通过移动ul来达到轮播的效果,所以ul的宽度要刚好放得下十张图片
  3. ol下的li是分页器,也就是我们看到的圆圈,类.current为选中状态
  4. clearfix类是清除浮动
<div class="jd_banner">
		<ul class="jd_wrap clearfix">
				<li><a href="javascript:;"><img src="uploads/l8.jpg" alt=""></a></li>
				<li><a href="javascript:;"><img src="uploads/l1.jpg" alt=""></a></li>
				<li><a href="javascript:;"><img src="uploads/l2.jpg" alt=""></a></li>
				<li><a href="javascript:;"><img src="uploads/l3.jpg" alt=""></a></li>
				<li><a href="javascript:;"><img src="uploads/l4.jpg" alt=""></a></li>
				<li><a href="javascript:;"><img src="uploads/l5.jpg" alt=""></a></li>
				<li><a href="javascript:;"><img src="uploads/l6.jpg" alt=""></a></li>
				<li><a href="javascript:;"><img src="uploads/l7.jpg" alt=""></a></li>
				<li><a href="javascript:;"><img src="uploads/l8.jpg" alt=""></a></li>
				<li><a href="javascript:;"><img src="uploads/l1.jpg" alt=""></a></li>
		</ul>
		<ol>
			<li class="current"></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
		</ol>
	</div>

css样式

.clearfix::before,
.clearfix::after{
    content: "";
    display: block;
    height: 0;
    line-height: 0px;
    clear: both;
    visibility: hidden;
}

.jd_banner {
  max-width: 640px;
  min-width: 320px;
  margin: 100px auto;
  width: 100%;
  position: relative;
  overflow: hidden;
}
.jd_banner .jd_wrap {
  width: 1000%;
  transform: translateX(-10%);
}
.jd_banner .jd_wrap li {
  width: 10%;
  float: left;
}
.jd_banner .jd_wrap li img {
  width: 100%;
}
.jd_banner ol {
  height: 10px;
  position: absolute;
  left: 50%;
  bottom: 3px;
  transform: translateX(-50%);
}
.jd_banner ol li {
  width: 6px;
  height: 6px;
  float: left;
  border: 1px solid #fff;
  margin-left: 10px;
  border-radius: 50%;
}
.jd_banner ol li.current {
  background: #fff;
}

轮播图效果

JS

  1. 我们主要通过控制index,translateX,监听过渡动画的结束(webkitTransitionEnd)来实现轮播
  2. 对index进行限制
  3. 相同的代码进行封装
  4. 优化代码
var jdCon = document.querySelector('.jd_banner')
	var ul = document.querySelector('.jd_banner>.jd_wrap')
	var index = 1
	var li = ul.querySelectorAll('li')
	var olLi = document.querySelectorAll('ol>li')
	var imgWidth = li[0].offsetWidth
	// 过渡移动的效果
	var transit = function(move){
		var move = move || 0
		ul.style.transition = 'all 0.5s linear'
		ul.style.transform = `translateX(${-imgWidth*index+move}px)`
	}
	// 瞬间定位效果
	var moment = function(distanceMove){
		var distanceMove = distanceMove || 0
		ul.style.transform = `translateX(${-imgWidth*index+distanceMove}px)`
		ul.style.transition = 'none'
	}
	window.onresize = function(){
		imgWidth = li[0].offsetWidth
	}
	var timer1 = setInterval(function(){
		index++;
		transit()
	}, 1000)
	ul.addEventListener('webkitTransitionEnd', function(){
		if(index>li.length-2){
			index = 1
			moment()
		}
		if(index<1){
			index = li.length-2
			moment()
		}
		document.querySelector('.current').classList.remove('current')
		olLi[index-1].classList.add('current')
	})
	var distanceStart = 0;
	var move = 0;
	var distanceEnd = 0;
	jdCon.addEventListener('touchstart',function(e){
		clearInterval(timer1)
		distanceStart = e.touches[0].clientX
	})
	jdCon.addEventListener('touchmove',function(e){
		var distance = e.touches[0].clientX
		move = distance - distanceStart
		moment(move)
	})
	jdCon.addEventListener('touchend',function(){
		if(move>imgWidth/2){
			index--
			transit()
		}else if(move<-imgWidth/2){
			index++
			transit()
		}else{
			transit()
		}
		distanceStart = 0;
		move = 0;
		distanceEnd = 0;
		timer1 = setInterval(function(){
			index++;
			transit()
		}, 1000)
	})

整体思路

  1. 首先做好布局,ul的子元素li要在一行上,无缝链接
  2. 利用css,ul的宽度为1000%, 设置transform: translateX(-10%);,使得不会显示展示给用户的最后一张图片,显示第一张图片
  3. 自动播放轮播图
  4. 利用定时器,让index每次加1,然后过渡滚动一张图片
var timer1 = setInterval(function(){
		index++;
		ul.style.transition = 'all 0.5s linear'
		ul.style.transform = `translateX(${-imgWidth*index}px)`
	}, 1000)
  1. 监听webkitTransitionEnd,过渡动画结束时,清除当前的类.current,给ol下的li[index]添加一个类
  2. 过渡动画结束后,如果index过大,我们要对其进行限制,当index为9,此时界面显示的是第十张图片,也就是用户看到的第一张图片,所以我们瞬间(在0s)让其移动到第一张,在令index=1
ul.addEventListener('webkitTransitionEnd', function(){
		// 当时间过渡结束
		// 添加.current
		if(index>8){
			// 当第一张移动完成后
			// 瞬间让index变为1
			ul.style.transform = `translateX(${-imgWidth}px)`
			ul.style.transition = 'none'
			index = 1
		}		document.querySelector('.current').classList.remove('current')
		olLi[index-1].classList.add('current')
	})
  1. ul跟随着手指的滑动而滑动,当手指滑动多少,ul跟着滑动多少
var distanceStart = 0;
	var move = 0;
	var distanceEnd = 0;
jdCon.addEventListener('touchstart',function(e){
		clearInterval(timer1)
		distanceStart = e.touches[0].clientX
	})
	jdCon.addEventListener('touchmove',function(e){
		var distance = e.touches[0].clientX
		move = distance - distanceStart
		ul.style.transform = `translateX(${-imgWidth*index+move}px)`
		ul.style.transition = 'none'
	})
  1. 滑动结束时做吸附效果
  2. 向右滑动时,如果滑动大于图片二分之一的宽度,当手指放开则加上过渡动画效果移动到上一张图片,此时我们移动始终是控制index
if(move>imgWidth/2){
			index--
			ul.style.transition = 'all 0.5s linear'
			ul.style.transform = `translateX(${-imgWidth*index}px)`
		}
  1. 向左滑动时,如果滑动大于图片二分之一的宽度,当手指放开则加上过渡动画效果移动到下一张图片,此时我们移动始终是控制index
else if(move<-imgWidth/2){
			index++
			ul.style.transition = 'all 0.5s linear'
			ul.style.transform = `translateX(${-imgWidth*index}px)`
		}
  1. 其它情况保持显示现状的图片
else{
			ul.style.transition = 'all 0.5s linear'
			ul.style.transform = `translateX(${-imgWidth*index}px)`
		}
  1. 最后所有的清0,开启定时器
  2. 相同代码封装,测试是否有bug,发现右滑有问题--------始终通过控制index来实现移动和切换ol分页器,要对index进行限制。对数字通过ul下的li.length来控制,将代码封装成可调用,可读性,逻辑性的代码
if(index<1){
			ul.style.transform = `translateX(${-imgWidth*8}px)`
			ul.style.transition = 'none'
			index = 8
		}

步骤

/*
	获取 必须知道的 变量

	步骤1: 不考虑过渡效果 直接 刷刷刷的 切换
		定时器中 index++
			    判断是否越界
			   修改 轮播图ul的 位置
			   考虑到 索引从1开始
			   css 默认 让ul 往左边窜一个屏幕宽度

	步骤2:	  下方的 索引li标签 修改 外观
		由于我们是使用.current 标示当前的索引值
		清空所有li的 class
		为当前的那个 li 添加current

	步骤3:然切换有动画效果
		使用css3中的transition
		.style.transition ='all .3s';
		在获取的时候 进行添加即可

	步骤4:当我切换到 最后一张时 瞬间 切到 第一张
		关闭过度
		瞬间切换到第一张

	步骤5:对代码 进行重构 添加进来了 过渡结束知识点
		由于 我们在修改 ul的位置时 会使用过度
		当注册了 过渡结束事件之后,每次 过渡完毕 都会 调用该事件
			将 判断 index  是否 越界 以及 修改 索引的 代码 全部 迁移到 过渡结束事件中

			定时器逻辑
				index++;

				修改 ul的 位置 ->开始过渡

			过渡结束事件逻辑
				判断 index是否有效
					进行修正
				修改索引li标签的 显示

	步骤6: 使用touch事件,实现 手指 拨动 ul滑动 效果
		touchstart
			记录开始值
			关闭定时器
			关闭过渡效果
		touchmove
			计算移动值
			修改ul的位置(在原始值的基础上进行修改,没有过渡效果的)
		touchend
			记录移动的距离(?)
			开启定时器(*)

*/

疑问

  1. 宽高必须考虑到移动web的适配方案
  2. 可能大家会把ul进行定位,ul定位(absolute),我们就无法把父盒子撑开,也就是父盒子jd_banner就没有高度,到时ol也很难定位,影响页面布局等问题
  3. 直接给父盒子设置高度,但是我们这个高度不好设置,因为不同的屏幕图片高度是不一致的
  4. 使用translateX来移动逻辑会更简单些
  5. 注意要样式重置,比如img要去掉基线
  6. clearfix可以不加,因为父盒子jd_banner已经设置overflow: hidden;会触发bfc

猜你喜欢

转载自blog.csdn.net/weixin_41105030/article/details/85710617