前端:HTML+CSS+JavaScript实现轮播图2
- 1. 和之前版本的区别
- 2. 实现原理
- 3. 针对上述的改进
- 3. 参考代码
1. 和之前版本的区别
之前发布的那篇关于轮播图的文章在这:前端:HTML+CSS+JavaScript实现轮播图,只能说存在问题吧!比如2、3实现效果是用了两个定时器实现的,虽然也达到了那种效果,但是从一些方面来说总有点繁琐吧!比如,在一定时间内图片移动像素的计算等。现在这个不需要计算,直接用一个定时器即可实现,我想说现在这个版本和各位在浏览器上看到那种效果实现原理应该差不多。
虽然没有给出相应的点击事件哈!
2. 实现原理
利用相对定位relative、绝对定位absolute、定时器、transition
结合relative、absolute来进行图片布局,用定时器来实现图片轮播间隔效果,用transition来实现每张图片移动过渡效果。
初始实现效果如上,这不符合我们想要的那种效果,这种是通过定时器每隔几秒变化每张图片的left的值的效果。这并不怎么美观,因为图片过渡效果并不符合我们的要求,但是如果显示的有多张图片,那么倒还不错,如下:
3. 针对上述的改进
就是把所有图片从左到右进行排列,外层用一个标签元素包裹,每隔一段时间变换外层的标签元素的left属性值。
3. 参考代码
这个是需要改进的代码哈!
main.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<link rel="stylesheet" href="./main.css">
</head>
<body>
<div class="main">
</div>
</body>
<script type="text/javascript" src="main.js"></script>
</html>
main.css
*{
padding: 0;
margin: 0;
}
ul{
list-style: none;
}
.main{
width: 500px;
height: 300px;
margin: 0 auto;
position: relative;
}
.dot{
height: 10px;
position: absolute;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
}
.dot span{
height: 100%;
float: left;
width: 10px;
border-radius: 50%;
margin-left: 10px;
cursor: pointer;
}
.dot span:first-child{
margin-left: 0;
}
.red{
background-color: red;
}
.white{
background-color: white;
}
.main ul{
position: relative;
height: 100%;
width: 100%;
overflow-x: hidden;
}
.main ul li{
position: absolute;
top: 0;
transition: all 0.3s;
width: 100%;
height: 100%;
}
.main ul li img{
width: 100%;
}
main.js
// 输入图片链接数组
const img_arr = [
'https://i0.hdslb.com/bfs/banner/627984a9617a35c7e4366e0c74baf29ef3aa96ae.png@976w_550h_1c_!web-home-carousel-cover.avif',
'https://i0.hdslb.com/bfs/banner/3464f3b055107b2b54b9443e02c43448c0915866.png@976w_550h_1c_!web-home-carousel-cover.avif',
'https://i0.hdslb.com/bfs/banner/ff7d11c786ddd45c218696c3c6b19c69a71883d7.jpg@976w_550h_1c_!web-home-carousel-cover.avif',
'https://i0.hdslb.com/bfs/sycp/creative_img/202311/74214ce12c94ba104322e2be463ec6f7.jpg@976w_550h_1c_!web-home-carousel-cover.avif'
];
const mainEle = document.querySelector('.main');
var _htmlStr = '';
img_arr.forEach(function(ele){
_htmlStr += `<li>
<img src="${ele}">
</li>`
})
var _htmlStr2 = '';
for(let i=0;i<img_arr.length;i++){
_htmlStr2 += '<span></span>'
}
var _htmlStr2 = `<div class="dot">${_htmlStr2}</div>`;
_htmlStr = `<ul>${_htmlStr}</ul>${_htmlStr2}`;
mainEle.innerHTML = _htmlStr;
const img_width = 500;
const elements = document.querySelectorAll('.main ul li');
const elements2 = document.querySelectorAll('.dot span');
elements.forEach(function(ele,index){
ele.style.left = index * img_width + 'px';
})
elements2.forEach(function(ele,index){
if(index == 0){
ele.className = 'red';
}else{
ele.className = 'white';
}
})
function left(){
elements.forEach(function(ele,index){
let left_v = parseFloat(ele.style.left);
if(left_v - img_width < 0){
ele.style.left = (elements.length - 1) * img_width + 'px';
}else{
ele.style.left = left_v - img_width + 'px';
}
if(left_v - img_width == 0){
elements2[index].className = 'red';
}else{
elements2[index].className = 'white';
}
})
}
var timer = setInterval(left,2000);
这个是改进版本
main.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<link rel="stylesheet" href="./main.css">
</head>
<body>
<div class="main">
<div class="pre_ul" id="main">
<ul>
<li><img src="https://i1.hdslb.com/bfs/archive/da52b26129a84aa316383d53e596d3f89c708294.jpg@672w_378h_1c_!web-home-common-cover.avif" alt=""></li>
<li><img src="https://i0.hdslb.com/bfs/archive/6df10d7e0834f8511ea620dbfe6bfc7b1eabdab2.jpg@672w_378h_1c_!web-home-common-cover.avif" alt=""></li>
<li><img src="https://i0.hdslb.com/bfs/archive/47338bc6056b6bbc906155590c6e201ae5dffee8.jpg@672w_378h_1c_!web-home-common-cover.avif" alt=""></li>
</ul>
</div>
<div class="dot" id="main">
<span class="red"></span>
<span class="white"></span>
<span class="white"></span>
</div>
</div>
</body>
<script type="text/javascript" src="main.js"></script>
</html>
main.css
*{
margin: 0;
padding: 0;
}
ul{
list-style: none;
}
.main{
width: 500px;
height: 300px;
position: relative;
margin: 0 auto;
overflow-x: hidden;
}
.main .dot{
position: absolute;
bottom: 8%;
left: 50%;
transform: translateX(-50%);
height: 12px;
z-index: 2;
}
.dot span{
float: left;
height: 100%;
width: 12px;
border-radius: 50%;
cursor: pointer;
margin-left: 8px;
}
.dot span:first-child{
margin-left: 0;
}
.white{
background-color: white;
}
.red{
background-color: red;
}
.main .pre_ul{
height: 100%;
position: absolute;
top: 0;
left: 0;
transition: all 0.5s;
z-index: 1;
}
.main .pre_ul ul{
width: 100%;
height: 100%;
position: relative;
overflow-x: hidden;
}
.main .pre_ul ul li{
height: 100%;
position: absolute;
top: 0;
left: 0;
}
.main .pre_ul ul li img{
width: 100%;
}
main.js
const img_width = 500;
// 图片最大宽度
const eles = document.querySelectorAll('.pre_ul ul li');
const pre_ul_ele = document.querySelector('.pre_ul');
const dots = document.querySelectorAll('.dot span');
const n = eles.length;
pre_ul_ele.style.left = 0;
pre_ul_ele.style.width = n * img_width + 'px';
eles.forEach(function(ele,index){
ele.style.width = img_width + 'px';
ele.style.left = index * img_width + 'px';
})
function clear_red(){
dots.forEach(function(ele,index){
ele.className = 'white';
})
}
var start_index = 0;
function left(){
pre_ul_ele.style.transition = 'all 0.5s';
let left_v = parseInt(pre_ul_ele.style.left);
pre_ul_ele.style.left = left_v - 500 + 'px';
clear_red();
start_index = (start_index+1)%n;
dots[start_index].className = 'red';
if(left_v - 500 == -n*img_width){
pre_ul_ele.style.left = 0;
}
}
var timer1 = setInterval(left,2000);
注:上述代码没有给出点击按钮变化图片特效,想实现的读者可以去看看上述第一个关于实现轮播图的版本哈!