js:原生实现轮播图

实现轮播图是前端学习的一门必修课,也是用来训练js能力。今天我用原生js写了个轮播图,包含无缝衔接、指示器、左右控制器等功能,跟大家分享。先看看效果图:
 

轮播图





1、下面是js代码:
        这些都是来获取html中的一些元素,这些简单的都不给大家说了,不会的可以看一下注释。下面来给大家说说一下如何实现这些代码的。

let data;
// 用于存储从服务器获取的照片数据

let banner_frame = document.querySelector('.banner_frame');
// 获取轮播图大框架元素

let banner = document.querySelector('.banner');
// 获取要轮播的框架元素

let img = document.querySelectorAll('.img');
// 获取类名为img的所有标签,返回一个数组对象

let left_arrows = document.querySelector('.left_arrows');
// 获取左箭头元素

let right_arrows = document.querySelector('.right_arrows');
// 获取右箭头元素

let left_pointer = document.querySelector('.left_pointer');
// 获取左圆点元素

let centre_pointer = document.querySelector('.centre_pointer');
// 获取中间指示器元素

let right_pointer = document.querySelector('.right_pointer');
// 获取右边指示器元素

let k = 0;
// 代表当前显示图片的下标,初始值为0

2、 第一步是ajax请求部分,简单的给大家说一下,因为上面有注释,大家可以看一下。这一块的主要就是吧json文件的数据给请求过来,然后是否请求成功,倾城成功句执行下一步,最后吧jaon格式的字符串转换成js对象,也就是js能理解的语言。

let xhr = new XMLHttpRequest();
// 声明一个XMLHttpRequest对象,用于进行AJAX请求获取服务器数据

xhr.open("get", "index.json", true);
// 打开AJAX请求,方法为GET,请求的JSON文件路径为index.json,第三个参数true表示异步加载

xhr.send();
// 发送AJAX请求

xhr.onreadystatechange = function() {
	// 响应执行函数、状态值改变时会触发这个函数

	if (xhr.readyState === 4 && xhr.status === 200) {
		// 当AJAX请求的状态发生改变时触发此函数
		// 4表示响应已准备就绪,200表示请求成功

		data = JSON.parse(xhr.responseText);
		// 将从服务器获取的JSON格式字符串转换为JavaScript对象并赋值给data

		render();
		// 调用render函数,将图片数据渲染到页面上
	}
};

3、主要就是渲染页面,吧这些东西渲染到页面上。
        声明一个str为空字符串,用来拼接图片;循环数据里面的长度;再拼接一下跟第一张图片实现无缝轮播;把拼接好的照片插入到要轮播的区域里面;把初始值指示器设为红色;

function render() {
	// 渲染函数

	let str = '';
	// 用于拼接图片HTML代码的字符串

	for (let i = 0; i < data.length; i++) {
		// 使用for循环遍历data数组,拼接图片的HTML代码
		str += '<img class="img" src="' + data[i].image + '" alt="" />';
	}
	str += '<img src="' + data[0].image + '" alt="" />';
	// 为实现无缝轮播,再添加一张和第一张图片一样的图片

	banner.innerHTML = str;
	// 将拼接好的图片HTML代码插入到要轮播的框架中

	left_pointer.style.backgroundColor = 'red';
	// 初始时设置左圆点的背景颜色为红色
}

4、就是实现点击右键头和自动轮播函数了,下面给大家解释一下,声明一个变量名=永久定时调用auto函数,设置时间;吧图片的宽获取过来,计算图片移动的距离;     让k++,设置过度时间和算出要轮播图片的距离;判断当前下标是否=图片的长度;设置一个一次性定时器让k=0,过度时间和图片移动距离,设为空;调用圆点指示器函数;

let int_box = setInterval(auto, 1500);
// 设置一个永久定时器,每隔1.5秒调用一次auto函数,实现自动轮播

let banner_width = banner_frame.offsetWidth;
// 获取轮播图大框架的宽度,用于后续计算图片移动距离
function auto() {
	// 自动轮播:右键头

	k++;
	// 每次调用auto函数,图片下标k自增1

	banner.style.transition = 'all 0.9s';
	// 设置图片切换的过渡效果,持续时间为0.9秒

	banner.style.marginLeft = -k * banner_width + 'px';
	// 根据当前下标计算图片移动的距离,使可视区域的banner向左移动

	if (k === data.length) {
		// 当图片下标k等于数据长度时,说明已经轮播到最后一张图片(拼接的那张)

		setTimeout(function() {
			// 设置一个一次性定时器,1秒后执行回调函数

			k = 0;
			// 将图片下标k重置为0,回到第一张图片

			banner.style.transition = 'all 0s';
			// 取消图片切换的过渡效果

			banner.style.marginLeft = '0px';
			// 将轮播框架的左边距设置为0,回到初始位置
		}, 1000);
	}
	update_pointer_color();
	// 更新指示器(圆点)的颜色	
}


5、讲解一下左键头函数是如何轮播起来;当图片的下标k=0时说明是第一张图片;如果图片不第一张那就k--,正常按照顺序执行;  设置一个一次性定时器;长度减一,让第一张图片迅速切换到下表2的图片上;设置过度时间和图片移动的距离,调用更新指示器颜色函数;

function autos() {
	// 左键头函数

	if (k === 0) {
		// 当图片下标k为0时,说明当前显示的是拼接的第一张图片
		k = data.length;
		// 将图片下标k设置为数据长度
		banner.style.transition = 'all 0s';
		// 取消图片切换的过渡效果
		banner.style.marginLeft = -k * banner_width + 'px';
		// 根据当前下标计算图片移动的距离,使可视区域的banner向左移动

		// 切换图片的时间,不用让用户看到切换图片的时间
		setTimeout(function() {
			// 设置一个一次性定时器,20毫秒后执行回调函数

			k = data.length - 1;
			// 将图片下标k设置为数据长度减1,回到倒数第张图片(即实际的第一张图片)
			banner.style.transition = 'all 0.9s';
			// 设置图片切换的过渡效果,持续时间为0.9秒

			banner.style.marginLeft = -k * banner_width + 'px';
			// 根据当前下标计算图片移动的距离,使可视区域的banner向左移动

			update_pointer_color();
			// 更新指示器(圆点)的颜色

			// 20毫秒内迅速从第一张回到第三张
		}, 20);
	} else {
		k--;
		// 图片下标k不为0时,将 k减1,切换到上一张图片
		banner.style.transition = 'all 0.9s';
		// 设置图片切换的过渡效果,持续时间为0.9秒
		banner.style.marginLeft = -k * banner_width + 'px';
		// 根据当前下标计算图片移动的距离,使可视区域的banner向左移动
		update_pointer_color();
		// 更新指示器(圆点)的颜色

		// 点击左键头正常轮播的事件
	}
}


6、更新指示器函数;调用重置小圆点函数(下面会交大家如何制作);算出当前图片的下标和圆点的下标;轮播到那一张图片就让对应的指示器变颜色;

function update_pointer_color() {
	// 更新圆点颜色 函数

	reset_pointers_color();
	// 重置所有圆点的背景颜色为白色

	let index = k % data.length;
	// 计算当前显示图片对应的圆点下标,通过取余操作实现循环
	// console.log('k'+k,'data'+data.length,'index'+index);
	document.getElementsByClassName('pointer')[index].style.backgroundColor = 'red';
	// 获取指示器,用下标的方式,让他们变为红色
}

7、重置指示器函数;吧左边、中间、右边、背景设置为白色;

function reset_pointers_color() {
	// 重置指示器的颜色

	left_pointer.style.backgroundColor = 'white';
	// 将左圆点的背景颜色设置为白色

	centre_pointer.style.backgroundColor = 'white';
	// 将中间指示器的背景颜色设置为白色

	right_pointer.style.backgroundColor = 'white';
	// 将右边指示器的背景颜色设置为白色
}

8、指示器函数;给小圆点加过度时间;和图片移动的距离;调用重置指示器的颜色函数;轮播到那一张图片就让对应的指示器变颜色;

function pointer_click(index) {
	// 指示器函数

	banner.style.transition = 'all 0.9s';
	// 设置图片切换的过渡效果,持续时间为0.9秒

	banner.style.marginLeft = -index * banner_width + 'px';
	// 根据传入的下标计算图片移动的距离,使可视区域的banner向左移动

	reset_pointers_color();
	// 重置所有圆点的背景颜色为白色

	document.getElementsByClassName('pointer')[index].style.backgroundColor = 'red';
	// 获取指示器,用传参的方式,让他们变为红色
}

9、下面就是鼠标的监听事件了,大概的意思给大家说一下:鼠标放上去就停止轮播,鼠标移开继续轮播;哦对了,别忘了调用函数哦。

banner_frame.addEventListener('mouseover', function() {
	// 当鼠标移入轮播图大框架时,清除自动轮播的定时器,停止轮播

	clearInterval(int_box);
});

banner_frame.addEventListener('mouseout', function() {
	// 当鼠标移出轮播图大框架时,重新设置定时器,继续自动轮播
	int_box = setInterval(auto, 1500);
});

10、下面就是给左右剪头添加一个节流事件,防止用户点击过来,轮播过程中出现混乱。

// 用于限制函数在指定时间间隔内只能执行一次
function throttle(func, delay) {
	// 记录上一次函数执行的时间戳
	let last_call = 0;
	// 初始值为0表示可以立即执行

	return function() {
		// 返回一个新的函数,这个函数会在被调用时检查时间间隔
		let now = new Date().getTime();
		// 获取当前时间戳(毫秒)

		if (now - last_call < delay) {
			// 检查当前时间与上次调用时间的差值是否小于设定的延迟时间
			// 如果小于延迟时间,说明距离上次调用时间太近,不执行函数
			return;
			// 直接返回,不执行目标函数
		}

		last_call = now;
		// 更新最后一次调用时间为当前时间

		return func.apply(this, arguments);
		// 使用apply方法调用原始函数
		// 这样可以保持正确的this上下文和参数传递
	};
}
left_arrows.addEventListener('click', throttle(autos, 1000));
// 使用节流函数包装auto函数,设置延迟时间为1000毫秒(1秒)
// 为左箭头添加点击事件监听器

right_arrows.addEventListener('click', throttle(auto, 1000));
// 为右箭头添加点击事件监听器  这样在1秒内多次点击只会执行一次

11、html代码:

<div class="banner_frame">
			<!-- 轮播图大框架 -->

			<div class="banner"></div>
			<!-- 要轮播的框架 -->

			<img class="left_arrows" src="./img/QQ20250402-132714.png" alt="" />
			<!-- 左箭头 -->

			<img class="right_arrows" src="./img/QQ20250402-132117.png" alt="" />
			<!-- 右键头 -->

			<div class="left_pointer pointer" onclick="pointer_click(0)"></div>
			<!-- 左 圆点 -->

			<div class="centre_pointer pointer" onclick="pointer_click(1)"></div>
			<!-- 中间 小圆点 -->

			<div class="right_pointer pointer" onclick="pointer_click(2)"></div>
			<!-- 右边 小圆点 -->
		</div>

 12、css的:

* {
	margin: 0;
	padding: 0;
}

.banner_frame {
	width: 400px;
	height: 300px;
	margin-top: 10%;
	margin-left: 36%;
	position: relative;
	display: flex;
	overflow: hidden;
	background-color: antiquewhite;
}

.banner {
	height: 300px;
	display: flex;
	background-color: aquamarine;
}

.banner img {
	width: 400px;
	height: 300px;
}

.left_arrows {
	width: 5%;
	height: 20px;
	position: absolute;
	margin-top: 140px;
	cursor: pointer;
}

.right_arrows {
	width: 5%;
	height: 20px;
	position: absolute;
	margin-top: 140px;
	margin-left: 95%;
	cursor: pointer;
}

.left_pointer{
	width: 4%;
	height: 13px;
	border-radius: 50%;
	position: absolute;
	margin-top: 71%;
	margin-left: 40%;
	background-color: white;
	cursor: pointer;
}

.centre_pointer{
	width: 4%;
	height: 13px;
	border-radius: 50%;
	position: absolute;
	margin-top: 71%;
	margin-left: 48%;
	background-color: white;
	cursor: pointer;
}

.right_pointer{
	width: 4%;
	height: 13px;
	border-radius: 50%;
	position: absolute;
	margin-top: 71%;
	margin-left: 56%;
	background-color: white;
	cursor: pointer;
}

13:json文件:

 

代码可能写的不是很好,存在很多不足,欢迎大家指点批评,我会努力去改正,有疑问欢迎留言,我会尽力去解答,谢谢大家花宝贵的时间来阅读这篇文章。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值