实现轮播图是前端学习的一门必修课,也是用来训练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文件:
代码可能写的不是很好,存在很多不足,欢迎大家指点批评,我会努力去改正,有疑问欢迎留言,我会尽力去解答,谢谢大家花宝贵的时间来阅读这篇文章。