JS实现轮播图2

JS实现轮播图2

​ 今天我们继续来介绍一下 轮播图 下面的indicator 区域的实现。 上一篇文章轮播图 我们重点介绍了实现原理,以及html 结构,这里基于之前的结构 编写 indicator 区域的实现。

在这里插入图片描述

思路分析

移动图片

红色框框的区域的实现,首先布局 给一个 绝对定位, 指定 bottom ,left,right 这些值 把这个区域定位到对应到右下角。

如何实现 点 小点 来移动 图片呢?

我们可以给每个 小点一个value 的属性,值为第几张图片的索引信息。

然后在父元素 绑定 点击事件, 通过事件冒泡的方式, 获取我们当前点击了哪个小点,然后获取value 值, 根据value 值计算 对应要偏离的距离

<div class="banner-dots">
  <span class="active" value="0"></span>
  <span class="" value="1"></span>
  <span class="" value="2"></span>
  <span class="" value="3"></span>
</div>

首先实现一个moveTo(index) ,此时 index 从零开始的, 根据index 来移动 carousel 的 transform 属性 translateX 的值,

比如

index=1 , 那说明要移动一个图片宽度的距离

index=2 , 那说明要移动两个个图片宽度的距离

依次类推。。。

// // 根据 index 移动carousel 位置
function moveTo(index) {
	let currentX = (parseInt(index)) * imgWidth * -1;
	// console.log('currentX:', currentX);
	carousel.style.transform = `translateX(${currentX}px)`;
}

绑定事件

我们在父元素 绑定 click 事件

bannerDots.addEventListener('click', function(e) {})		

当鼠标点击 子元素的时候,事件会冒泡传递到父元素的click 的事件上,父元素如何知道 点击了哪个元素呢?

我们可以通过 funciton(e){} 来获取这个event, 通过 e.target 就可以获取对应的 元素了, 然后获取元素对应的索引,然后可以使用 moveTo(index) 来进行移动 图片。 同时 我们还要控制 当前激活的图片,即当前要展示的图片。 我们需要给当前的图片 添加一个样式,或者类 来区分。 然后还要把之前的状态置为 未激活的状态。

在这里插入图片描述

激活对应的状态

我的做法就是把所有的点都找到 然后去掉 active class , 然后在当前的图片上重新添加 active class 这样 就完成了,小点跟随的变化。

对应active 宽度 稍微大一点,来区分。

.container .banner-dots span.active {
  width: 20px;
}

同理 left,right 的移动, 也要对小点的区域进行联动,这个时候 我们只需要 计算出当前是第几张图片,首先 重置所有小点的状态, 然后进行激活当前的图片。

完整实现

html 页面以及 css 布局如下

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>流浪法师</title>

		<script src="./slides.js" defer></script>
		<style>
			* {
				padding: 0;
				margin: 0;
				box-sizing: border-box;
			}

			h1 {
				text-align: center;
				margin: 25px auto;
			}

			.container {
				position: relative;
				margin: 30px auto;
				width: 782px;
				height: 573px;
				overflow: hidden;
				background-color: #f5f5f5;
			}


			.carousel {
				display: flex;
				flex-wrap: nowrap;
				transition: all 0.2s;
			}

			.carousel>.item {
				width: 782px;
				height: 573px;
				flex: 0 0 782px;
			}

			.carousel>.item>img {
				height: 100%;
				width: 100%;
				object-fit: cover;
				object-position: center top;

			}

			.container .left,
			.container .right {
				width: 70px;
				height: 70px;
				position: absolute;
				top: 50%;
				transform: translateY(-50%);
				text-align: center;
				color: #f1f1f1;
				line-height: 55px;
				font-size: 55px;
				vertical-align: bottom;
				background: rgba(28, 31, 33, .1);
				border-radius: 50%;
			}


			.container .left {
				left: 0;
			}

			.container .right {
				right: 0;
			}

			.container .left:hover,
			.container .right:hover {
				background: rgba(28, 31, 33, .5);
				border-radius: 50%;
				cursor: pointer;
				font-weight: 500;
				color: #fff;
			}
			
			.container .banner-dots {
				position: absolute;
				bottom: 20px;
				left: 0;
				right: 0;
				text-align: right;
				padding-right: 24px;
				line-height: 12px;
			}

			.container .banner-dots span {
				display: inline-block;
				width: 8px;
				height: 8px;
				border-radius: 4px;
				margin-left: 8px;
				background: rgba(255, 255, 255, .75);
				transition: all .2s;
				cursor: pointer;
			}

			.container .banner-dots span:hover {
				cursor: pointer;
				width: 20px;
			}

			.container .banner-dots span.active {
				width: 20px;
			}
		</style>
	</head>
	<body>

		<div class="wrapper">
			<h1>流浪法师</h1>
			<div class="container">
				<div class="carousel">
					<div class="item"><img src="./img/守护者雕像 瑞兹1.jpeg" alt=""></div>
					<div class="item"><img src="./img/美国大叔 瑞兹2.jpeg" alt=""></div>
					<div class="item"><img src="./img/部落精神 瑞兹3.jpeg" alt=""></div>
					<div class="item"><img src="./img/符文法师4.jpeg" alt=""></div>
				</div>

				<div class="left" onclick="">&lt;</div>
				<div class="right" onclick="">&gt;</div>

				<div class="banner-dots">
					<span class="active" value="0"></span>
					<span class="" value="1"></span>
					<span class="" value="2"></span>
					<span class="" value="3"></span>
				</div>
			</div>

		</div>


	</body>
</html>

JavaScript 如下

slide.js

// 获取dom 结点 
let left = document.querySelector('.left');
let right = document.querySelector('.right');
let carousel = document.querySelector('.carousel');

let bannerDots = document.querySelector('.banner-dots');
let allSpans = document.querySelectorAll('.banner-dots > span');


// 图片总的数量
const imgCount = 4;

// 一张图片基本宽度
const imgWidth = 782;

// 默认第一张图片偏移 的位置
let currentX = 0;

// 边界位置
const maxTranslateX = imgWidth * (imgCount - 1);



// 确定当前的位置是 第几张 图片
function assureIndex(currentX) {
	currentX = Math.abs(currentX)
	index = currentX / imgWidth
	// console.log('index:', index);
	return index;
}

// 根据 index 寻找 第几张图片
function lookTarget(index) {
	// body > div > div > div.banner-dots > span:nth-child(1)
	position = index + 1;
	const target = span = document.querySelector(`.banner-dots > span:nth-child(${position})`)
	// console.log('span:', span, 'index:', index);
	return target;
}


// 移除所有的allSpans acitve 的类
function removeAllActive() {
	for (let i = 0; i < allSpans.length; i++) {
		span = allSpans[i];
		span.classList.remove('active');
	}
}

// 激活 indicator 区域
function acitveTarget(currentX) {
	const index = assureIndex((currentX));
	const target = lookTarget(index);
	removeAllActive();
	target.classList.add('active');
}


left.addEventListener('click', function() {
	// console.log('click left');
	if (currentX === 0) {
		// 显示最后一张图片
		currentX += imgWidth * (imgCount - 1) * -1;
	} else if (Math.abs(currentX) <= maxTranslateX) {
		// 没有超出范围 正常移动即可
		currentX += imgWidth;
	} else {
		currentX = 0;
	}

	// setting  translateX  偏移方向
	carousel.style.transform = `translateX(${currentX}px)`;
	acitveTarget(currentX);
})



right.addEventListener('click', function() {
	// console.log('click right');
	// 没有超出范围就正常移动,currentX  - imgWidth
	if (Math.abs(currentX) < maxTranslateX) {
		currentX -= imgWidth;
	} else {
		// 显示第一张 幻灯片
		currentX = 0;
	}
	// setting  translateX  偏移方向
	carousel.style.transform = `translateX(${currentX}px)`;
	acitveTarget(currentX);
})


// 根据 index 移动carousel 位置
function moveTo(index) {
	let currentX = (parseInt(index)) * imgWidth * -1;
	// console.log('currentX:', currentX);
	carousel.style.transform = `translateX(${currentX}px)`;
}



bannerDots.addEventListener('click', function(e) {
	// console.log(e.target);
	// 获取点击了那个 span 标签
	const target = e.target;
	const index = target.getAttribute('value');

	// console.log('index:', index);
	moveTo(index);
	// 移除所有的 active
	removeAllActive();
	// 添加当前的active
	target.classList.add('active');

})

/*
https://developer.mozilla.org/zh-TW/docs/Web/API/Element/classList
https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttribute
*/

总结

本文为 轮播图第二弹,完成了indicator 区域的联动效果,感兴趣的同学 可以尝试自己来写一下看看哦。

参考链接

classList

getAttribute

分享快乐,留住感动. '2022-07-12 21:30:05' --frank
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值