效果图
Tips:
小圆点,鼠标移入轮播暂停、移出轮播继续、移入显示左右箭头、移出隐藏左右箭头等等效果未予实现,个人认为这些意义不大,重点在于理解轮播图背后的实现原理。
轮播图的原理
在已有图片的列表中各加一张图,头部加最后一张图,尾部加第一张图:
<ul class="loop">
<li><img src="./banner1.jpg" /></li>
<li><img src="./banner2.jpg" /></li>
<li><img src="./banner3.jpg" /></li>
</ul>
当然是通过js添加,加了之后的结构是:
<ul class="loop">
<li><img src="./banner3.jpg" /></li>
<li><img src="./banner1.jpg" /></li>
<li><img src="./banner2.jpg" /></li>
<li><img src="./banner3.jpg" /></li>
<li><img src="./banner1.jpg" /></li>
</ul>
默认显示banner1
,在点击上一张的时候去判断边界值,在左移到banner3
之后,悄悄将过渡效果关闭并将图片右移至第2
个banner3
图片处(用户无感知),点击下一张图片的边界值也类比处理。
注意点
1.首尾各加一张图的目的是为了初次点击时能有过渡效果且好背后进行移动的暗箱操作
2.一定要等过渡完成后才进行移动的暗箱操作,所以会使用延时器setTimeout
,且时延 === 过渡时间
3.为防止用户点击速度过快,一定要进行节流处理
小拓展
为什么大家实现轮播图的时候获取dom
元素都写的是document.querySelector
,而不是document.getElementBy
系列?
querySelector
返回的是一个 Static Node List
,而 getElementsBy
系列的返回的是一个 Live Node List
。前者是快照,在之后再添加新的元素,不会影响已查询的结果;后者可以理解为一个对象地址,地址固定但内容不固定,会跟随你之后的节点操作而动态改变。
完整代码
<!DOCTYPE html>
<html>
<head>
<title>手写轮播图</title>
<style type="text/css">
body {
text-align: center;
}
.wrap {
width: 400px;
border: 1px solid #eeeeee;
margin: 100px auto;
overflow: hidden;
}
.loop {
display: flex;
list-style: none;
padding: 0;
margin: 0;
}
.loop li img {
width: 400px;
height: 300px;
vertical-align: bottom;
}
</style>
</head>
<body>
<div class="wrap">
<ul class="loop">
<li><img src="./banner1.jpg" /></li>
<li><img src="./banner2.jpg" /></li>
<li><img src="./banner3.jpg" /></li>
</ul>
</div>
<button onclick="prev()">上一张</button>
<button onclick="next()">下一张</button>
<script type="text/javascript">
{
// 在前后各加一张图,目的是为了能无缝滑动
const loop = document.querySelector('.loop')
const li = document.querySelectorAll('.loop li')
loop.insertBefore(li[li.length -1].cloneNode(true), li[0])
loop.appendChild(li[0].cloneNode(true))
loop.style.transform = 'translateX(-400px)'
// 定义一些变量
let now = 1 //当前在哪一张
let timer = null // 定时器
function prev() {
if(!timer) { // 作节流处理
loop.style.transition = '.3s';
loop.style.transform = `translateX(-${--now * 400}px)`
timer = setTimeout(() => {
if (!now) {
now = li.length
loop.style.transition = 'none';
loop.style.transform = `translateX(-${now * 400}px)`
}
timer = null
}, 300)
}
}
function next() {
if(!timer) { // 节流处理
loop.style.transition = '.3s';
loop.style.transform = `translateX(-${++now * 400}px)`
timer = setTimeout(() => {
if (now > li.length) {
now = 1
loop.style.transition = 'none';
loop.style.transform = `translateX(-${now * 400}px)`
}
timer = null
}, 300)
}
}
// 自动轮播
setInterval(next, 2000)
}
</script>
</body>
</html>
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!