手搓js轮播图
- 逻辑解析
- html结构
- 图片切换方法
- 圆点导航切换效果
- 左右箭头点击切换
- 圆点导航点击切换
- 自动播放,介入暂停
- 完整代码
逻辑解析
css的样式我就不再进行讲述,如果有需求可以评论区告诉我,我再出一篇文章进行详细讲解
js轮播图最主要的核心逻辑就是在于如何进行切换和自动切换播放(虽然听起来像废话,但是)
那么接下来步入正题
html结构
这里以五张300px的图片为例,你可能会疑惑为什么放了六张?
因为最后第五张到头之后切换回第一张的时候,我门要在第五张后面放一张第一张的图片。
目的防止切换效果突兀,看起来像是循环连续的,而不是跨查(拟声词)直接奔回第一张
<body>
<div class="lunbo-outer">
<ul id="lunbolist">
<li><img src="./img/A1.jpg" alt="" title="1"></li>
<li><img src="./img/A2.jpg" alt="" title="2"></li>
<li><img src="./img/A3.jpg" alt="" title="3"></li>
<li><img src="./img/A4.jpg" alt="" title="4"></li>
<li><img src="./img/A5.jpg" alt="" title="5"></li>
<li><img src="./img/A1.jpg" alt="" title="6"></li>
</ul>
<div class="lunbodian">
<span title="1"></span><span title="2"></span><span title="3"></span><span title="4"></span><span title="5"></span>
</div>
<p class="zuoqie"><</p>
<p class="youqie">></p>
</div>
</body>
实际结构就像下面的图片,就好比你从你家窗户向外看行驶的火车(先假设你家旁边有条火车轨道),你通过窗户之能看到一节一节的火车车厢在切换,而不是整条火车。
图片切换方法
先获取相应的文档节点,这里要清楚DOM对应的html结构,不然后面的逻辑处理会有点绕
var lunboOuter = document.querySelector('.lunbo-outer');
var lunbolist = document.getElementById('lunbolist');
var zuoqie = document.querySelector('.zuoqie');
var youqie = document.querySelector('.youqie');
var lunbodianspan = document.querySelector('.lunbodian').children;
var spanindex=0;
然后就是js方法,具体含义直接看代码注释
//图片向右切换效果函数
function move(){
//1500是5张300px的图片,负值是因为火车向前走,它的left是负值
if(lunbolist.offsetLeft<=-1500){
lunbolist.style.left='0px';
}
//根据list的left属性值得知现在播放的是第几张
var afterleft=lunbolist.offsetLeft;
if (afterleft/-300>=4) {
//>=4表示现在是播放的第五张,下一张就是第一张
//spanmove()方法是切换图片下方的导航点,第一个点索引是0
spanmove(0);
}else{
//否则切换下一个点
spanmove(afterleft/-300+1);
}
//利用定时器制作切换动画,每10毫秒移动4个像素
var timer=setInterval(function(){
lunbolist.style.left = lunbolist.offsetLeft-4 + 'px';
//如果切换到位了,就停止
if(afterleft-lunbolist.offsetLeft>=300){
clearInterval(timer);
}
},10)
}
//图片向左切换效果函数同理
function unmove(){
if(lunbolist.offsetLeft>=0){
lunbolist.style.left='-1500px';
}
var afterleft=lunbolist.offsetLeft;
if (afterleft/-300<=0) {
spanmove(4);
}else{
spanmove(afterleft/-300-1);
}
var timer=setInterval(function(){
lunbolist.style.left = lunbolist.offsetLeft+4 + 'px';
if(afterleft-lunbolist.offsetLeft<=-300){
clearInterval(timer);
}
},10)
}
圆点导航切换效果
这里用的方法是先一致后特殊,先让它们都一个颜色,然后判断该谁了就让谁特殊色
//小圆点切换效果
function spanmove(index){
for (let i = 0; i < lunbodianspan.length; i++) {
//这里的颜色与css保持一致
lunbodianspan[i].style.backgroundColor = 'rgba(43, 43, 43, 0.4)';
}
lunbodianspan[index].style.backgroundColor = 'white';
}
左右箭头点击切换
为了使得切换有序,这里增加一个限制条件,只能在切换到位完成的情况下才可以切换,否则在切换动画过程中不可以进行切换操作
//点击左右箭头切换效果
youqie.onclick=function(){
if(lunbolist.offsetLeft%300==0){
move();
}
}
zuoqie.onclick=function(){
if(lunbolist.offsetLeft%300==0){
unmove();
}
}
圆点导航点击切换
点第几个点播放第几张图片
//为小圆点绑定点击切换效果
for(let i=0;i<lunbodianspan.length;i++){
lunbodianspan[i].onclick=function(){
lunbolist.style.left=-i*300+'px';
spanmove(i);
}
}
自动播放,介入暂停
鼠标移入的时候大概率表示用户有要操作播放的“嫌疑”,所以暂定自动播放,把操作权给用户,当用户把鼠标移走的时候再开始自动播放。
//自动轮播效果
var timerone=setInterval(move,2200);
lunboOuter.onmouseenter=function(){
clearInterval(timerone);
}
lunboOuter.onmouseleave=function(){
timerone=setInterval(move,2200);
}
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>轮播模板</title>
<style>
*{
margin: 0;
padding: 0;
}
li{
list-style: none;
}
.lunbo-outer{
width: 300px;
height: 300px;
overflow: hidden;
margin: 100px auto;
position: relative;
}
#lunbolist{
width: 1800px;
height: 300px;
display: flex;
position: absolute;
}
#lunbolist li{
width: 300px;
height: 300px;
}
#lunbolist li img{
width: 100%;
height: 100%;
}
.lunbodian{
position: absolute;
bottom: 10px;
right: calc(50% - 50px);
}
.lunbodian span{
display: inline-block;
width: 10px;
height: 10px;
background-color: rgba(43, 43, 43, 0.4);
border-radius: 50%;
margin: 0 4px
}
.lunbodian span:nth-child(1){
background-color: rgb(255, 255, 255);
}
.lunbodian span:hover{
background-color: rgb(255, 255, 255);
}
.zuoqie, .youqie{
width: 20px;
height: 50px;
background-color: rgba(22, 22, 22, 0.6);
position: absolute;
line-height: 50px;
text-align: center;
cursor: pointer;
color: white;
}
.zuoqie:hover, .youqie:hover{
background-color: darkgray;
}
.zuoqie{
top: 135px;
}
.youqie{
top: 135px;
right: 0;
}
</style>
</head>
<body>
<div class="lunbo-outer">
<ul id="lunbolist">
<li><img src="./img/A1.jpg" alt="" title="1"></li>
<li><img src="./img/A2.jpg" alt="" title="2"></li>
<li><img src="./img/A3.jpg" alt="" title="3"></li>
<li><img src="./img/A4.jpg" alt="" title="4"></li>
<li><img src="./img/A5.jpg" alt="" title="5"></li>
<li><img src="./img/A1.jpg" alt="" title="6"></li>
</ul>
<div class="lunbodian">
<span title="1"></span><span title="2"></span><span title="3"></span><span title="4"></span><span title="5"></span>
</div>
<p class="zuoqie"><</p>
<p class="youqie">></p>
</div>
<script>
var lunboOuter = document.querySelector('.lunbo-outer');
var lunbolist = document.getElementById('lunbolist');
var zuoqie = document.querySelector('.zuoqie');
var youqie = document.querySelector('.youqie');
var lunbodianspan = document.querySelector('.lunbodian').children;
var spanindex=0;
//图片向右切换效果函数
function move(){
if(lunbolist.offsetLeft<=-1500){
lunbolist.style.left='0px';
}
var afterleft=lunbolist.offsetLeft;
if (afterleft/-300>=4) {
spanmove(0);
}else{
spanmove(afterleft/-300+1);
}
var timer=setInterval(function(){
lunbolist.style.left = lunbolist.offsetLeft-4 + 'px';
if(afterleft-lunbolist.offsetLeft>=300){
clearInterval(timer);
}
},10)
}
//图片向左切换效果函数
function unmove(){
if(lunbolist.offsetLeft>=0){
lunbolist.style.left='-1500px';
}
var afterleft=lunbolist.offsetLeft;
if (afterleft/-300<=0) {
spanmove(4);
}else{
spanmove(afterleft/-300-1);
}
var timer=setInterval(function(){
lunbolist.style.left = lunbolist.offsetLeft+4 + 'px';
if(afterleft-lunbolist.offsetLeft<=-300){
clearInterval(timer);
}
},10)
}
//小圆点切换效果
function spanmove(index){
for (let i = 0; i < lunbodianspan.length; i++) {
lunbodianspan[i].style.backgroundColor = 'rgba(43, 43, 43, 0.4)';
}
// console.log(index);
lunbodianspan[index].style.backgroundColor = 'white';
}
//点击左右箭头切换效果
youqie.onclick=function(){
if(lunbolist.offsetLeft%300==0){
move();
}
}
zuoqie.onclick=function(){
if(lunbolist.offsetLeft%300==0){
unmove();
}
}
//为小圆点绑定点击切换效果
for(let i=0;i<lunbodianspan.length;i++){
// console.log(i);
lunbodianspan[i].onclick=function(){
lunbolist.style.left=-i*300+'px';
spanmove(i);
}
}
//自动轮播效果
var timerone=setInterval(move,2200);
lunboOuter.onmouseenter=function(){
// console.log(1);
clearInterval(timerone);
}
lunboOuter.onmouseleave=function(){
// console.log(2);
timerone=setInterval(move,2200);
}
</script>
</body>
</html>
Tips:
css样式根据自己的需求自行改动
图片大小根据自己的图片自行改动