当前位置:网站首页>37.轮播图
37.轮播图
2022-08-04 19:46:00 【Suyuoa】
目录
先把结构搞好
一共三张轮换图像,调整的差不多后将后两张图像隐藏起来
html
<!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>Document</title>
<link rel="stylesheet" href="轮播图.css">
</head>
<body>
<div class="rotate">
<div class="content">
<a href="#"><img src="upload/1.jpeg" alt=""></a>
<a href="#"><img src="upload/2.jpeg" alt=""></a>
<a href="#"><img src="upload/3.jpeg" alt=""></a>
</div>
<div class="left"></div>
<div class="right"></div>
<ul class="bottom">
<li class="current"></li>
<li></li>
<li></li>
</ul>
</div>
</body>
</html>
css
* {
margin: 0px;
padding: 0px;
box-sizing: content-box;
}
li {
list-style: none;
}
.rotate {
position: relative;
left:50%;
transform: translate(-50%,0);
width:500px;
height:300px;
overflow: hidden;
}
.content {
width:300%;
height:100%;
display: flex;
}
.content a {
width:100%;
height:100%;
}
.content img {
width:100%;
height:100%;
z-index: -1;
}
.left,.right {
position:absolute;
top:50%;
transform: translate(0,-50%);
width:23px;
height:43px;
/* background-color: red; */
}
.left {
left:0px;
background-image:url(images/border_left.png);
}
.right {
right:0px;
background-image:url(images/border_right.png);
}
.bottom {
position: absolute;
bottom:0px;
left:50%;
transform: translate(-50%,0);
display: flex;
align-items: center;
justify-content: space-around;
width:100px;
height:20px;
}
.bottom li {
width:10px;
height:10px;
background-color:white;
border-radius: 5px;
}
.bottom .current {
background-color: skyblue;
}
轮播图主要有下面几个功能
- 左右按钮
- 当鼠标进入轮播图后,按钮处于显示状态,离开后处于隐藏状态
- 左右按键可以用动画效果切换不同轮播图
- 下面的三个li
- 第一张图被展示,那么第一个li的样式就与其他的li不同
- 点击任意一个li可以按索引切换不同的图像
- 轮播图本身
- 当鼠标不在轮播图内,轮播图自动播放,离开轮播图后,轮播图停止播放
还有其他一些需要改进的地方,我随着就写了
讲解轮播图的视频为P317-P328 06-网页轮播图-结构搭建_哔哩哔哩_bilibili
我与视频中的方法略有不同
1 左右按钮显示与隐藏
2 动态生成索引li
先数出来有几张轮播图,只会再添加几个li,最后把第一个li设置为current
效果与之前相同
3 左右按键无缝滚动原理
我们像让轮播图切换到最后一张图像的时候,之后无缝切换到第一张,这个时候我们需要在content的最后克隆第一张轮播图,这样我们就可以做出由3号滚动到1号的效果
- 黑色框为可视区域
在我们滚动到新克隆的1的时候,不使用动画直接把content的位置搞到第一张
由于两张图像完全一样,所以人眼不会分辨出来
上面是向右边滚的情况,从右往左滚也是一样
我们现在在2这里
由于是向左滚,我们正常滚到1
滚到1之后直接瞬移到克隆出来的1
这样就可以正常滚到3了
下面的代码我就与课程上写的不一样的,感兴趣的话可以看一下课程
4 克隆最后一张图像
克隆这张图像没什么好说的,这里注意我li_num是在克隆之前获取的,并且没有再次赋值li_num,所以我li_num就是图像的数量
5 li的检测
我通过 移动的位置与图像的宽度判断li的位置,比如0就是第0个li,-500就是第一个li。我现在有3张图像,就有3个li,它们的编号依次是0,1,2
由于要做到无缝滚动,所以我们要考虑两个例外
第一个例外是我 从左到右 滚动到 我新克隆出来的图像1,也就是current_li_index为3的时候,当从左到右滚动到克隆1时,我的li的编号要为0
第二个例外是我 从右到左 滚动到 我新克隆出来的图像1,也就是current_li_index为-1的时候,当从右到左滚动到克隆1时,我的li的编号要为0
- 可以用逻辑或写在一起,我这里这样写比较方便理解
之后做了一个排他
最后 每15ms检测一次li的位置,并随位置的变化而变化
6 li的点击功能
我们点击li要能切换到指定的图像,方法是给每一个li一个位置属性,然后点哪个li,就移动到对应的位置
7 右键点击功能
首先右键点击功能与自动播放功能是一样的,点击需要点一下,自动播放不需要点,所以我搞了一个函数方便后面复用
这里首先拿到两个位置,第一个位置是克隆1的位置,第二个位置是第三张图像的位置,因为向右点击要做无缝切换,这两个位置就是例外
下面我们进行一个判断,判断条件是(1000,1500]
注意我这里是先判断,在执行动作,在3->克隆1执行后,位置正好是1000,不满足判断条件
也就是说我这个判断条件只会 出现 在 克隆1->3的情况
如果我不加这个判断,它就会从 克隆1回滚到2,加了之后,在克隆1的时候,然后点击右键,依然会滚动到-500,但在克隆1时满足判断条件,所以会先瞬移会图像1,然后滚动倒-500
之后当前li的索引自加,然后进行判断(这里可以不用判断,为了与左键点击代码对称所以加了一下),这里的判断意思是,如果当前li的索引右溢出,将distance置于克隆1位置,其余情况照常
最后播放动画,函数外添加点击事件
8 左键点击功能
与右键点击功能逻辑相同,第一个判断是[0,-500),也就是由图像1移动到图像2的时候,瞬移到克隆1,然后从 克隆1到图像3
9 自动播放功能
- auto_play_timer = null会释放掉定时器,以求减少内存的占用
我们让打开页面后自动播放,鼠标离开轮播图的时候自动播放,进入轮播图的时候停止播放
你也可以不把自动播放函数提出来,而是使用element.click()进行模拟点击
10 节流阀
节流阀的作用是放置轮播图连续点击导致播放过快,方法是当上一个函数动画内容执行完毕,再去执行下一个函数动画,让事件无法连续触发
- 这个节流阀可加可不加,如果不加也没什么问题
我们如果想要动画结束后再执行某个函数,我们就要加入立即执行函数
在这里可以这样写
经测试效果一样
之后对右侧按钮加入节流阀
之后对左侧按钮加入节流阀
这样在动画进行的过程中,再按按钮就没有用了
11 源码
html
在html中可以加入新的轮播图
<!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>Document</title>
<link rel="stylesheet" href="轮播图.css">
<script src="animation.js"></script>
</head>
<body>
<div class="rotate">
<div class="content">
<a href="#"><img src="upload/1.jpeg" alt=""></a>
<a href="#"><img src="upload/2.jpeg" alt=""></a>
<a href="#"><img src="upload/3.jpeg" alt=""></a>
<a href="#"><img src="upload/4.png" alt=""></a>
</div>
<div class="left"></div>
<div class="right"></div>
<ul class="bottom">
<!-- <li class="current"></li>
<li></li>
<li></li> -->
</ul>
</div>
</body>
<script src="轮播图.js"></script>
</html>
css
在css中可以改
- .rotate width 轮播图区域宽度
- .rotate height 轮播图区域高度
- content width 轮播图图像大小,这里需要根据轮播图的数量变化而变化
* {
margin: 0px;
padding: 0px;
box-sizing: content-box;
}
li {
list-style: none;
}
.rotate {
position: relative;
left:50%;
transform: translate(-50%,0);
width:500px;
height:300px;
overflow: hidden;
}
.content {
position: absolute;
width:500%; /*轮播图图片数量+1,比如你有四张图就用500%,3张图就用400%*/
height:100%;
display: flex;
}
.content a {
cursor: default;
width:100%;
height:100%;
}
.content img {
width:100%;
height:100%;
z-index: -1;
}
.left,.right {
position:absolute;
top:50%;
transform: translate(0,-50%);
width:23px;
height:43px;
display: none;
cursor: pointer;
}
.left {
left:0px;
background-image:url(images/border_left.png);
}
.right {
right:0px;
background-image:url(images/border_right.png);
}
.bottom {
position: absolute;
bottom:0px;
left:50%;
transform: translate(-50%,0);
display: flex;
align-items: center;
justify-content: space-around;
width:100px;
height:20px;
}
.bottom li {
width:10px;
height:10px;
background-color:white;
border-radius: 5px;
cursor: pointer;
}
.bottom .current {
background-color: skyblue;
}
JS
在JS中可以改
- img_width 轮播图区域大小
- throttle 全部设置为true可以关闭节流阀
left_btn = document.querySelector('.left')
right_btn = document.querySelector('.right')
rotate = document.querySelector('.rotate')
content = document.querySelector('.content')
bottom = document.querySelector('.bottom')
// 左右按钮显示与隐藏,自动播放
rotate.addEventListener('mouseenter',function() {
left_btn.style.display = 'block';
right_btn.style.display = 'block';
clearInterval(auto_play_timer)
auto_play_timer = null
})
rotate.addEventListener('mouseleave',function() {
left_btn.style.display = 'none';
right_btn.style.display = 'none';
auto_play_timer = setInterval(function() {auto_play()},2000)
})
auto_play_timer = setInterval(function() {auto_play()},2000)
// 动态生成索引li
li_num = content.children.length
for (i=0;i<li_num;i++) {
li = document.createElement('li')
bottom.appendChild(li)
}
first_li = bottom.querySelector('li')
first_li.className = 'current'
// 添加最后一张图像
new_first_img = content.firstElementChild.cloneNode(true)
content.appendChild(new_first_img)
// 确定当前是哪一个li
img_width = 500
all_lis = bottom.querySelectorAll('li')
function which_li() {
current_li_index = Math.round(-content.offsetLeft / img_width)
if (current_li_index == li_num) {
current_li_index = 0
}
if (current_li_index == -1) {
current_li_index = 0
}
for (i=0;i<all_lis.length;i++) {
all_lis[i].className = ''
}
all_lis[current_li_index].className = 'current'
}
setInterval(which_li,15)
// li的点击功能
for (i=0;i<all_lis.length;i++) {
all_lis[i].distance = i * -img_width
all_lis[i].addEventListener('click',function() {
move_animation(content,this.distance)
})
}
throttle = true
// 右侧按钮切换
new_create_img_position = -li_num * img_width //-1500
last_img_position = -(li_num-1) * img_width //-1000
function auto_play() {
if (throttle) {
throttle = false
if (content.offsetLeft >= new_create_img_position && content.offsetLeft < last_img_position) {
content.style.left = '0px'
}
current_li_index = current_li_index + 1
if (current_li_index == li_num) {
distance = new_create_img_position
}
else {
distance = current_li_index * -img_width
}
move_animation(content,distance,function() {throttle = true})
}
}
right_btn.addEventListener('click',function() {auto_play()})
// 左侧按钮切换
second_img_position = -img_width //-500
left_btn.addEventListener('click',function() {
if (throttle) {
throttle = false
if (content.offsetLeft > second_img_position && content.offsetLeft <= 0) {
content.style.left = new_create_img_position + 'px'
}
current_li_index = current_li_index - 1
if (current_li_index == -1) {
distance = last_img_position
}
else {
distance = current_li_index * -img_width
}
move_animation(content,distance,function() {throttle = true})
}
})
边栏推荐
猜你喜欢
随机推荐
Regular expression is incomplete
Yuanguo chain game system development
VQ Realization of Wavelet Extraction Features
使用 Chrome 开发者工具 coverage 功能分析 web 应用的渲染阻止资源的执行分布情况
Highlights of some performance tests
5G NR 笔记记录
性能测试流程
泰山OFFICE技术讲座:底纹、高亮、边框的关系
华为交换机:STP测试实验
Switch node version and switch npm source tool
【有奖征文】秋招特训,打造你的专属产品体验
宏定义小方法
对比几类主流的跨端技术方案
MYSQL获取数据库的表名和表注释
June To -.-- -..- -
awk 统计平均 最大 最小值
Quantitative trading robot system development
LED的C语言应用程序
七夕福利!中奖名单:书籍免费送!
hash和history路由的区别