前端JS案例(二):自动轮播+手动拨动

一、自动轮播

1、定义index,记录索引值

2、获取必要的变量:单个元素的宽度、轮播图ul的长度、ul中li的数组

3、设置定时器setInterval,因为是无限轮播,不用清除

4、过度结束,判断index索引值是否有效


html代码:

<!-- 顶部的 轮播图 -->
		<div class="jd_banner">
			<ul class="banner_images clearfix">
				<li><a href="#"><img src="images/l8.jpg" alt=""></a></li>
				<li><a href="#"><img src="images/l1.jpg" alt=""></a></li>
				<li><a href="#"><img src="images/l2.jpg" alt=""></a></li>
				<li><a href="#"><img src="images/l3.jpg" alt=""></a></li>
				<li><a href="#"><img src="images/l4.jpg" alt=""></a></li>
				<li><a href="#"><img src="images/l5.jpg" alt=""></a></li>
				<li><a href="#"><img src="images/l6.jpg" alt=""></a></li>
				<li><a href="#"><img src="images/l7.jpg" alt=""></a></li>
				<li><a href="#"><img src="images/l8.jpg" alt=""></a></li>
				<li><a href="#"><img src="images/l1.jpg" alt=""></a></li>
			</ul>
			<ul class="banner_index clearfix">
				<li class='current'></li>
				<li></li>
				<li></li>
				<li></li>
				<li></li>
				<li></li>
				<li></li>
				<li></li>
			</ul>
		</div>

JS代码:

function banner() {

	//1 获取变量
	// 屏幕的宽度
	var width = document.body.offsetWidth;
	// console.log(width);\

	//  获取 轮播图的ul
	var moveUl = document.querySelector('.banner_images');
	
	// 添加过度效果 由于后面已经设置了 所以 这里 已经没有意义了
	// moveUl.style.transition = 'all .3s';

	// 索引的li标签
	var indexLiArr = document.querySelectorAll('.banner_index li');

	// 定义 index 记录 当前的 索引值
	// 默认 我们的ul 已经 往左边 移动了 一倍的宽度
	// (为什么 一位 最左边的图片 是用来做无限轮播的 不希望用户看到) 所以 index =1
	var index = 1;

	// 开启定时器
	var timeId = setInterval(function () {
		// 累加
		index++;

		// 将 过渡开启 管你三七二十一 只要进来 就开启过渡 保证 过渡效果一直存在
		moveUl.style.transition = 'all .3s';

		// 修改 ul的位置
		moveUl.style.transform = 'translateX('+index*width*-1+'px)';

	},1000);


	// 过渡 结束事件 用来 修正 index的值 并修改索引
	moveUl.addEventListener('webkitTransitionEnd',function () {
		console.log('过渡结束');

		//  如果 index 太大了 
		if (index>8) {
			index = 1;

			// 关闭过渡
			moveUl.style.transition = '';

			// 瞬间 修改一下 ul 的位置
			moveUl.style.transform = 'translateX('+index*width*-1+'px)';
		}else if(index<1){
			// 跳到倒数第二张
			index= 8;

			// 关闭过渡
			moveUl.style.transition = '';

			// 瞬间 修改一下 ul 的位置
			moveUl.style.transform = 'translateX('+index*width*-1+'px)';
		}

		// 修改 索引li标签的 class
		for (var i = 0; i < indexLiArr.length; i++) {
			indexLiArr[i].className = '';
		}

		// 有一个 1的 差值
		indexLiArr[index-1].className = 'current';

	})

二、手动拨动

1、移动端特有事件:不能通过dom.ontouchstart的方式绑定,只能用addEventListener的方式绑定。

    touchstart:事件参数中有触摸点的值

    touchmove:事件参数中有触摸点的值

    touchend:事件参数中没有触摸点的值

常见的左滑、右滑、长按、捏合等事件都是由touch的这三个事件组合而成。

2、视口属性不能忘:meta:vp+tab


移动端touch事件:

<script type="text/javascript" >
	window.onload  = function () {
		// 元素的 事件 绑定时 如果写了 形参 会接受到一个 实参,
		// 触摸 开始的时候 被触发

		// 定义 变量 保存 开始的 坐标值
		var startX = 0;

		// 定义变量 保存 移动的距离
		var moveX = 0;

		// 定义变量 用来 记录 小div 结束的时候 移动的距离
		var distanceX = 0;


		// 定义 一堆 记录y方向 移动的 值
		var startY = 0;
		var moveY = 0;
		var distanceY =0;

		document.body.addEventListener('touchstart',function (event) {
			console.log('touchstart');
			// console.log(event);
			// 获取 起始的 坐标值
			startX = event.touches[0].clientX;
			startY = event.touches[0].clientY;
			console.log('startX:'+startX);
		})

		// 手指开始移动时会 一直触发
		document.body.addEventListener('touchmove',function (event) {
			console.log('touchmove');
			// console.log(event);
			// 这样 就能够获取到 我在X方向移动的距离了
			moveX = event.touches[0].clientX -startX;
			console.log('moveX:'+moveX);

			moveY = event.touches[0].clientY -startY;
			// 直接 修改 div的 transform
			// 由于两边 是 字符串拼接 中间是 计算 一定要 加上括号 否则会当 字符串凭借
			// document.querySelector("div").style.transform = 'translateX('+(moveX+distanceX)+'px)';
			document.querySelector("div").style.transform = 'translate('+(distanceX+moveX)+'px,'+(distanceY+moveY)+'px)';
		})

		// 手指 抬起来的时候 会触发
		document.body.addEventListener('touchend',function (event) {
			console.log('touchend');
			// console.log(event);

			// 移动 结束的时候 记录 移动的距离
			// distanceX = moveX +distanceX;
			distanceX+=moveX;
			
			distanceY+=moveY;
		})
	}
</script>


二、手动轮播:

// 注册 三个 touch事件

	// 定义变量 记录 开始的X
	var startX = 0;

	// 记录移动的值
	var moveX = 0;

	// 记录 distanceX
	var distanceX = 0;


	// 触摸开始
	moveUl.addEventListener('touchstart',function (event) {
		// 关闭定时器
		clearInterval(timeId);

		// 关闭过渡效果
		moveUl.style.transition = '';

		// 记录开始值
		startX = event.touches[0].clientX;

	})

	// 触摸中
	moveUl.addEventListener('touchmove',function (event) {
		// 计算移动的值
		moveX = event.touches[0].clientX - startX;

		// 移动ul
		// 默认的移动值是 index*-1*width 
		moveUl.style.transform = 'translateX('+(moveX+index*-1*width)+'px)';
	})

	// 触摸结束
	/*
		手指松开的时候 判断 移动的距离 进行 是否吸附
			由于 不需要考虑 正负 只需要考虑 距离 Math.abs()
				吸附回的值是 index*-1*width
			如果移动的距离较大
				需要判断正负
					index++;
					index--;
					 index*-1*width
	*/
	moveUl.addEventListener('touchend',function (event) {

		// 定义 最大的 偏移值
		var maxDistance = width/3;

		// 判断 是否超过
		if (Math.abs(moveX)>maxDistance) {
			// 判断 到底是 往左 还是往右移动
			if (moveX>0) {
				index--;
			}else{
				index++;
			}
			// 为了好看 将 过渡效果开启
			moveUl.style.transition = 'all .3s';

			// 吸附 一整页
			moveUl.style.transform = 'translateX('+(index*-1*width)+'px)';

		}else{
			// 如果 进到这里了 说明 没有超过 我们定义的 最大偏移值 吸附回去即可

			// 为了好看 将 过渡效果开启
			moveUl.style.transition = 'all .3s';

			// 吸附回去
			moveUl.style.transform = 'translateX('+(index*-1*width)+'px)';
		}

		// 记录结束值

		// 开启定时器
		timeId = setInterval(function () {
			// 累加
			index++;

			// 将 过渡开启 管你三七二十一 只要进来 就开启过渡 保证 过渡效果一直存在
			moveUl.style.transition = 'all .3s';

			// 修改 ul的位置
			moveUl.style.transform = 'translateX('+index*width*-1+'px)';
		},1000)
	})

JS优化:

function banner() {

	//1 获取变量
	// 屏幕的宽度
	var width = document.body.offsetWidth;
	// console.log(width);\

	//  获取 轮播图的ul
	var moveUl = document.querySelector('.banner_images');
	
	// 添加过度效果 由于后面已经设置了 所以 这里 已经没有意义了
	// moveUl.style.transition = 'all .3s';

	// 索引的li标签
	var indexLiArr = document.querySelectorAll('.banner_index li');

	// 定义 index 记录 当前的 索引值
	// 默认 我们的ul 已经 往左边 移动了 一倍的宽度
	// (为什么 一位 最左边的图片 是用来做无限轮播的 不希望用户看到) 所以 index =1
	var index = 1;


	// 抽取的代码 提升代码的可读性,以及 降低维护的难度
	var startTransition = function () {
		moveUl.style.transition = 'all .3s';
	}

	var endTransition = function () {
		moveUl.style.transition = '';
	}

	// 由于 移动的距离 无法确定 所以提取为参数
	var setTransform = function (distance) {
		moveUl.style.transform = 'translateX('+distance+'px)';
	}


	// 开启定时器
	var timeId = setInterval(function () {
		// 累加
		index++;

		// 将 过渡开启 管你三七二十一 只要进来 就开启过渡 保证 过渡效果一直存在
		// moveUl.style.transition = 'all .3s';
		startTransition();

		// 修改 ul的位置
		// moveUl.style.transform = 'translateX('+index*width*-1+'px)';
		setTransform(index*width*-1);

	},1000);


	// 过渡 结束事件 用来 修正 index的值 并修改索引
	moveUl.addEventListener('webkitTransitionEnd',function () {
		console.log('过渡结束');

		//  如果 index 太大了 
		if (index>8) {
			index = 1;

			// 关闭过渡
			// moveUl.style.transition = '';
			endTransition();

			// 瞬间 修改一下 ul 的位置
			// moveUl.style.transform = 'translateX('+index*width*-1+'px)';
			setTransform(index*width*-1);
		}else if(index<1){
			// 跳到倒数第二张
			index= 8;

			// 关闭过渡
			// moveUl.style.transition = '';
			endTransition();

			// 瞬间 修改一下 ul 的位置
			// moveUl.style.transform = 'translateX('+index*width*-1+'px)';
			setTransform(index*width*-1);
		}

		// 修改 索引li标签的 class
		for (var i = 0; i < indexLiArr.length; i++) {
			indexLiArr[i].className = '';
		}

		// 有一个 1的 差值
		indexLiArr[index-1].className = 'current';

	})


	// 注册 三个 touch事件

	// 定义变量 记录 开始的X
	var startX = 0;

	// 记录移动的值
	var moveX = 0;

	// 记录 distanceX
	var distanceX = 0;


	// 触摸开始
	moveUl.addEventListener('touchstart',function (event) {
		// 关闭定时器
		clearInterval(timeId);

		// 关闭过渡效果
		// moveUl.style.transition = '';
		endTransition();

		// 记录开始值
		startX = event.touches[0].clientX;

	})

	// 触摸中
	moveUl.addEventListener('touchmove',function (event) {
		// 计算移动的值
		moveX = event.touches[0].clientX - startX;

		// 移动ul
		// 默认的移动值是 index*-1*width 
		// moveUl.style.transform = 'translateX('+(moveX+index*-1*width)+'px)';
		setTransform(moveX+index*-1*width);
	})

	// 触摸结束
	/*
		手指松开的时候 判断 移动的距离 进行 是否吸附
			由于 不需要考虑 正负 只需要考虑 距离 Math.abs()
				吸附回的值是 index*-1*width
			如果移动的距离较大
				需要判断正负
					index++;
					index--;
					 index*-1*width
	*/
	moveUl.addEventListener('touchend',function (event) {

		// 定义 最大的 偏移值
		var maxDistance = width/3;

		// 判断 是否超过
		if (Math.abs(moveX)>maxDistance) {
			// 判断 到底是 往左 还是往右移动
			if (moveX>0) {
				index--;
			}else{
				index++;
			}
			// 为了好看 将 过渡效果开启
			// moveUl.style.transition = 'all .3s';
			startTransition();

			// 吸附 一整页
			// moveUl.style.transform = 'translateX('+(index*-1*width)+'px)';
			setTransform(index*-1*width);

		}else{
			// 如果 进到这里了 说明 没有超过 我们定义的 最大偏移值 吸附回去即可

			// 为了好看 将 过渡效果开启
			// moveUl.style.transition = 'all .3s';
			startTransition();

			// 吸附回去
			// moveUl.style.transform = 'translateX('+(index*-1*width)+'px)';
			setTransform(index*-1*width);
		}

		// 记录结束值

		// 开启定时器
		timeId = setInterval(function () {
			// 累加
			index++;

			// 将 过渡开启 管你三七二十一 只要进来 就开启过渡 保证 过渡效果一直存在
			// moveUl.style.transition = 'all .3s';
			startTransition();

			// 修改 ul的位置
			// moveUl.style.transform = 'translateX('+index*width*-1+'px)';
			setTransform(index*width*-1);
		},1000)
	})

}

二、手动拨动(二)


// 页面加载完毕事件
window.onload = function () {
	// 左边的滑动效果
	left_scroll();
}

// 左边的滑动效果
/*
	1. 获取一些必须知道的东西
		移动的dom元素 移动的ul
			获取 ul父盒子的 高度
			获取 ul的高度
			获取移动的 最大值 最小值

	2.通过touch事件 进行滑动
	3.手指松开 吸附回去
		touchend事件
			吸附回去
*/
function left_scroll() {
	// 1获取 必须知道的东西

	// 获取移动的ul
	var moveUl = document.querySelector(".main_left ul");

	// ul父盒子的高度	
	var parentHeight = document.querySelector(".main_left").offsetHeight;

	// 获取 header的高度 将下部的偏移值 进行计算
	var headerHeight = document.querySelector('.header').offsetHeight;

	// ul的高度
	var ulHeight = moveUl.offsetHeight;

	// 计算移动的范围 因为 往上移动个是 y负方向 所有 这里 是减去 而不是加
	var minDistance = parentHeight - ulHeight - headerHeight;

	var maxDistance = 0;


	// 定义变量 用来 标示 吸附的 距离
	var delayDistance = 150;

	// console.log('最小值'+minDistance);
	// console.log('最大值'+maxDistance);

	// 2.通过touch事件 修改 ul的移动
	// 定义一些变量 记录 距离
	//  起始值
	var startY  = 0;
	// 移动值
	var moveY = 0;
	// 总的移动距离
	var distanceY = 0

	// 将 重复的代码 进行封装
	var startTransition = function () {
		moveUl.style.transition = 'all .5s';
	}
	var endTransition = function () {
		moveUl.style.transition = '';
	}
	var setTransform = function (distance) {
		moveUl.style.transform = 'translateY('+distance+'px)';
	}


	moveUl.addEventListener('touchstart',function(event){
		startY = event.touches[0].clientY;
	})
	moveUl.addEventListener('touchmove',function(event){
		moveY = event.touches[0].clientY - startY;

		// 判断 是否满足 移动的条件
		if ((moveY+distanceY)>(maxDistance+delayDistance)) {
			// 修正 moveY
			moveY = 0;
			distanceY = maxDistance+delayDistance;
			// 为什么是减法 因为 往上移动 是负值 要比最小值 还要更小
		}else if((moveY+distanceY)<(minDistance-delayDistance)){
			// 修改 moveY
			moveY = 0;
			distanceY = minDistance-delayDistance;
		}	

		// 关闭 过渡效果
		// moveUl.style.transition = '';
		endTransition();
		// 移动
		// moveUl.style.transform = 'translateY('+(moveY+distanceY)+'px)';
		setTransform(moveY+distanceY);
	})
	moveUl.addEventListener('touchend',function(event){
		// 修改移动的总距离
		distanceY+=moveY;

		// 吸附回去 判断 吸附的方位
		if (distanceY>maxDistance) {
			distanceY = maxDistance;
		}else if(distanceY<minDistance){
			distanceY = minDistance;
		}

		// 吸附回去
		// 移动
		// moveUl.style.transition  ='all .5s';
		startTransition();
		// moveUl.style.transform = 'translateY('+(distanceY)+'px)';
		setTransform(distanceY);
	})


	//  第二大部分逻辑  点击 跳转
	/*
		逻辑1
		绑定tap事件绑定给ul即可 
			事件参数中是能够拿到 触发该事件的 dom元素

		逻辑2
			获取 点击的li标签的 索引值
				让我们的ul 移动 索引值 * li的高度的 距离
					索引值获取
						可以再for循环中获取
					为每一个li 保存一个 索引属性
						<body  data-index='1'>
						点击li的时候 获取该属性的值即可
						dom.dataSet['index'];

	*/

	// 在使用之前 先获取
	// 获取 当前点击的 li标签的 索引值  每一个li标签的 高度
	var liHeight = document.querySelector('.main_left ul li').offsetHeight;

	// 用之前 为li标签 绑定一个 data-index 属性
	// 为所有的li 绑定data-index
	var liArr = document.querySelectorAll('.main_left ul li');

	// js绑定 自定义属性
	for (var i = 0; i < liArr.length; i++) {
		// dataset['index'] 如果 html标签中 已经有了 data-index属性 那么是 赋值操作
		// 如果 html标签中 没有 data-index属性 那么是 添加该属性的操作
		liArr[i].dataset['index'] = i;
	}

	fox_tap(moveUl,function(e){
		console.log('触发了tap事件');
		console.log(e);
		// 获取的是a标签
		console.log(e.target);
		// 获取 a标签的 父盒子 就是 li标签
		console.log(e.target.parentNode);


		// 修改 当前点击的 li标签的 class
		// 清空 所有的
		for (var i = 0; i < liArr.length; i++) {
			liArr[i].className = '';
		}
		// 高亮当前的 
		e.target.parentNode.className = 'current';

		// 知道 当前 点击的li标签的 index
		var currentIndex = e.target.parentNode.dataset['index'];
		console.log('索引值为:'+currentIndex);


		// 计算 移动的距离
		var moveDistance = currentIndex*liHeight*-1;


		// 对 moveDistance 进行修正
		if (moveDistance>maxDistance) {
			// 如果大于最大值,将他 改回来 
			moveDistance = maxDistance;
		}else if(moveDistance <minDistance){
			// 如果 小于最小值 将他 改回 最小值
			moveDistance = minDistance;
		}


		// 开始移动
		startTransition();

		// moveDistance 就是一个 符合要求的值
		setTransform(moveDistance);

	})


}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值