一、无缝连续滚动特效
1、无缝连续滚动原理
比如有6张图片,依次为0~5
那么将相同的0~5图片拼接在后面进行滚动
当第二组图片的第0个图片移动到滚动区域的左侧时(即第一组图片移动完)时,立即将图片从头开始继续移动即可
2、无缝连续滚动代码实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.box {
width: 1000px;
height: 130px;
border: 1px solid #000;
margin: 50px auto;
overflow: hidden;
}
.box ul {
list-style: none;
/* 设置大一点,这样li才能浮动 */
width: 5000px;
position: relative;
}
.box ul li {
float: left;
margin-right: 10px;
}
</style>
</head>
<body>
<div id="box" class="box">
<ul id="list">
<li><img src="https://juejin.cn/post/images/number/0.png" ></li>
<li><img src="https://juejin.cn/post/images/number/1.png" ></li>
<li><img src="https://juejin.cn/post/images/number/2.png" ></li>
<li><img src="https://juejin.cn/post/images/number/3.png" ></li>
<li><img src="https://juejin.cn/post/images/number/4.png" ></li>
<li><img src="https://juejin.cn/post/images/number/5.png" ></li>
</ul>
</div>
<script>
var box = document.getElementById('box');
var list = document.getElementById('list');
// 复制多一遍所有的li
list.innerHTML += list.innerHTML;
// 全局变量,表示当前list的left值
var left = 0;
// 定时器,全局变量
var timer;
move();
// 动画封装成函数
function move() {
// 设表先关,防止动画积累
clearInterval(timer);
timer = setInterval(function () {
left -= 4;
// 每张图宽200px,加上缝隙为1260px
if (left <= - 1260) {
left = 0;
}
list.style.left = left + 'px';
}, 20);
}
// 鼠标进入停止定时器
box.onmouseenter = function () {
clearInterval(timer);
};
// 鼠标离开继续定时器
box.onmouseleave = function () {
move();
};
</script>
</body>
</html>
复制代码
二、跑马灯轮播图特效
2-1、实现原理与注意事项
假设现要轮播5张图片,实现点击右按钮来播放下一张图片,点击左按钮来播放上一张图片。
2-1-1、布局轮播图,实现点击右按钮切换下一张图片
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.carousel {
width: 650px;
height: 360px;
border: 1px solid #000;
margin: 50px auto;
position: relative;
overflow: hidden;
}
.carousel ul {
list-style: none;
width: 6000px;
position: relative;
left: 0px;
transition: left .5s ease 0s;
}
.carousel ul li {
float: left;
}
.carousel .leftbtn {
position: absolute;
left: 20px;
top: 50%;
margin-top: -25px;
width: 50px;
height: 50px;
background-color: rgb(226, 68, 28);
border-radius: 50%;
}
.carousel .rightbtn {
position: absolute;
right: 20px;
top: 50%;
margin-top: -25px;
width: 50px;
height: 50px;
background-color: rgb(226, 68, 28);
border-radius: 50%;
}
</style>
</head>
<body>
<div class="carousel">
<ul id="list">
<li><img src="https://juejin.cn/post/images/beijing/0.jpg" ></li>
<li><img src="https://juejin.cn/post/images/beijing/1.jpg" ></li>
<li><img src="https://juejin.cn/post/images/beijing/2.jpg" ></li>
<li><img src="https://juejin.cn/post/images/beijing/3.jpg" ></li>
<li><img src="https://juejin.cn/post/images/beijing/4.jpg" ></li>
</ul>
<!-- href写成空的javascript以防止页面刷新 -->
<a href="javascript:;" class="leftbtn" id="leftbtn"></a>
<a href="javascript:;" class="rightbtn" id="rightbtn"></a>
</div>
<script>
// 得到按钮和ul,ul整体进行运动
var leftbtn = document.getElementById('leftbtn');
var rightbtn = document.getElementById('rightbtn');
var list = document.getElementById('list');
var idx = 0; // 表示此时处于第几张图
rightbtn.onclick = function () {
idx++; // 点击一次图片序号+1
list.style.left = -idx * 650 + 'px'; // 表示向左移动的位置,每张图宽度为650
}
</script>
</body>
</html>
复制代码
- 需要注意的是,每张图以浮动的方式排列,ul宽度要足够大才能将li排列开来
- 我们可为ul的left属性添加过渡效果,使得移动时更加丝滑
此时,我们会发现当我们不断点击时,轮播到第五张图后再次点击右按钮,图片变成了空白,那么我们如何实现轮播到最后一张图后紧接着从第一张开始轮播呢?
2-1-2、实现最后一张图片与第一张图片衔接轮播效果
实现原理:
- 将第一张图克隆一份追加到最后一张图后面,这样轮播到最后一张图后再次点击看到的便是第一张图
- 为了再次点击按钮时变成第二张图,那么我们可以在移动到克隆图片后快速将ul元素的left置为0即可
- 这里我们给ul添加了过渡动画,动画时长为0.5s,所以我们要等动画时长过后再快速将ul的left置为0
- 在将ul的left快速置为0时是不需要肉眼察觉到的,所以此处要将过渡效果去除
// 得到按钮和ul,ul整体进行运动
var leftbtn = document.getElementById('leftbtn');
var rightbtn = document.getElementById('rightbtn');
var list = document.getElementById('list');
// 克隆第一张图片,追加到后面
var cloneli = list.firstElementChild.cloneNode(true);
list.appendChild(cloneli);
var idx = 0; // 表示此时处于第几张图
rightbtn.onclick = function () {
// 为了防止重置ul时将transition置为了'none',这里还原一下
list.style.transition = 'left .5s ease 0s';
idx++; // 点击一次图片序号+1
if (idx > 4) {
// 在动画时长过后将ul快速重置回去
setTimeout(function () {
list.style.transition = 'none';
list.style.left = 0;
idx = 0;
}, 500);
}
list.style.left = -idx * 650 + 'px'; // 表示向左移动的位置,每张图宽度为650
}
复制代码
2-1-3、优化:添加节流锁防止快速点击轮播图播放异常
由于此处轮播图播放的过渡动画为500毫秒,所以我们可以设置一个节流锁
var idx = 0; // 表示此时处于第几张图
var lock = true;
rightbtn.onclick = function () {
if (!lock) { return }
lock = false; // 锁住
// 为了防止重置ul时将transition置为了'none',这里还原一下
list.style.transition = 'left .5s ease 0s';
idx++; // 点击一次图片序号+1
if (idx > 4) {
// 在动画时长过后将ul快速重置回去
setTimeout(function () {
list.style.transition = 'none';
list.style.left = 0;
idx = 0;
}, 500);
}
list.style.left = -idx * 650 + 'px'; // 表示向左移动的位置,每张图宽度为650
setTimeout(function () {
lock = true;
}, 500);
}
复制代码
2-1-4、实现点击左按钮,切换上一张轮播图
- 如果已经是第一张轮播图了,则点击左按钮期望切换到最后一张图,那么就需要瞬间移动到拼接到最后面的克隆图片上(去除过渡效果);然后添加上过渡效果,将轮播图移动到真正的最后一张图片上
- 如果不是第一张轮播图,则idx — 正常移动即可
leftbtn.onclick = function () {
if (!lock) return;
lock = false;
// 判断是不是第0张,如果是,就要瞬间用假的替换真的
if (idx == 0) {
// 取消掉过渡,因为要的是瞬间移动,不是“咕噜”过去
list.style.transition = 'none';
// 直接瞬间移动到最后的假图片上
list.style.left = -5 * 650 + 'px';
// 设置一个延时器,这个延时器的延时时间可以是0毫秒,虽然是0毫秒,但是可以让我们过渡先是瞬间取消,然后再加上
setTimeout(function () {
// 加过渡
list.style.transition = 'left .5s ease 0s';
// idx改为真正的最后一张
idx = 4;
list.style.left = -idx * 650 + 'px';
}, 0);
} else {
idx--;
list.style.left = -idx * 650 + 'px';
}
// 函数节流
setTimeout(function () {
lock = true;
}, 500);
}
复制代码
需要注意的是,如果已经是第一张图,那么点击左按钮时要取消过渡然后瞬间移动到克隆图片上,然后再加上过渡移动到真正的最后一张图片上,这里恢复过渡时利用了setTimeout是为了让取消过渡的瞬移起效果,不然瞬间移动还是会有过渡效果。
2-2、完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.carousel {
width: 650px;
height: 360px;
border: 1px solid #000;
margin: 50px auto;
position: relative;
overflow: hidden;
}
.carousel ul {
list-style: none;
width: 6000px;
position: relative;
left: 0px;
transition: left .5s ease 0s;
}
.carousel ul li {
float: left;
}
.carousel .leftbtn {
position: absolute;
left: 20px;
top: 50%;
margin-top: -25px;
width: 50px;
height: 50px;
background-color: rgb(226, 68, 28);
border-radius: 50%;
}
.carousel .rightbtn {
position: absolute;
right: 20px;
top: 50%;
margin-top: -25px;
width: 50px;
height: 50px;
background-color: rgb(226, 68, 28);
border-radius: 50%;
}
</style>
</head>
<body>
<div class="carousel">
<ul id="list">
<li><img src="https://juejin.cn/post/images/beijing/0.jpg" ></li>
<li><img src="https://juejin.cn/post/images/beijing/1.jpg" ></li>
<li><img src="https://juejin.cn/post/images/beijing/2.jpg" ></li>
<li><img src="https://juejin.cn/post/images/beijing/3.jpg" ></li>
<li><img src="https://juejin.cn/post/images/beijing/4.jpg" ></li>
</ul>
<!-- href写成空的javascript以防止页面刷新 -->
<a href="javascript:;" class="leftbtn" id="leftbtn"></a>
<a href="javascript:;" class="rightbtn" id="rightbtn"></a>
</div>
<script>
// 得到按钮和ul,ul整体进行运动
var leftbtn = document.getElementById('leftbtn');
var rightbtn = document.getElementById('rightbtn');
var list = document.getElementById('list');
// 克隆第一张图片追加到list中
var cloneLi = list.firstElementChild.cloneNode(true);
list.appendChild(cloneLi);
// 表示滚动到了第几个图片
var idx = 0;
// 设置一个节流锁,防止快速点击
var lock = true;
rightbtn.onclick = function () {
if (!lock) { return }
lock = false;
// 为了防止滚动到最后最后一张图后快速移动图片置第一张后去除掉了动画,要在点击时添加一遍
list.style.transition = 'left .5s ease 0s';
idx++;
if (idx > 4) {
// 在动画0.5s执行完毕后瞬间将list的left值置为0
setTimeout(() => {
list.style.transition = 'none';
list.style.left = 0;
idx = 0;
}, 500)
}
// 这里每张图片宽度是650px
list.style.left = -idx * 650 + 'px';
setTimeout(() => {
lock = true
}, 500);
}
leftbtn.onclick = function () {
if (!lock) { return }
lock = false;
if (idx == 0) {
list.style.transition = 'none';
// 直接瞬间移动到最后的假图片上
list.style.left = -5 * 650 + 'px';
// 设置一个延时器,这个延时器的延时时间可以是0毫秒,虽然是0毫秒,但是可以让我们过渡先是瞬间取消,然后再加上
setTimeout(function () {
// 加过渡
list.style.transition = 'left .5s ease 0s';
// idx改为真正的最后一张
idx = 4;
list.style.left = -idx * 650 + 'px';
}, 0);
} else {
idx--;
list.style.left = -idx * 650 + 'px';
}
setTimeout(() => {
lock = true
}, 500)
}
</script>
</body>
</html>
复制代码
总结:跑马灯轮播图的要点是,所有的图片以浮动的方式排成一排,父元素改变left值进行移动;此外为了能够起到轮播的效果,要克隆第一张图片拼接到最后:
- 在移动到最后一张图片再次向后移动时,先移动到克隆图片上,然后再瞬间让left变为0再进行移动(如果有过渡动画需要注意需要设置延时器,在动画效果结束后再重置回去)
- 在移动到第一张图片再次先前移动时,需要先瞬移到克隆图片上,然后再移动到真正的最后一张图片上
三、呼吸灯轮播图特效
3-1、实现原理
与跑马灯轮播图特效不同的是,呼吸灯特效需要各个轮播图堆叠在一起,以上一张“淡出”下一张“淡入”的方式来实现效果,也不需要克隆第一张图拼接到最后。
- 首先使用定位的方式,让各个轮播图堆叠展示,将第一张轮播图的opacity置为1,其余轮播图置为0,为了实现淡出淡入效果,可为ul添加opacity的过渡动画
- 当点击左/右按钮时,让当前轮播图的opacity变为0,上一张/下一张轮播图的opacity变为1即可
- 同样需要节流锁的使用,比如过渡动画时间为1s则锁打开的时长也设置为1s
3-2、代码实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.carousel {
width: 650px;
height: 360px;
border: 1px solid #000;
margin: 50px auto;
position: relative;
}
.carousel ul {
list-style: none;
}
.carousel ul li {
position: absolute;
top: 0;
left: 0;
/* 透明度都是0 */
opacity: 0;
transition: opacity 1s ease 0s;
}
/* 只有第一张透明度是1 */
.carousel ul li:first-child {
opacity: 1;
}
.carousel .leftbtn {
position: absolute;
left: 20px;
top: 50%;
margin-top: -25px;
width: 50px;
height: 50px;
background-color: rgb(28, 180, 226);
border-radius: 50%;
}
.carousel .rightbtn {
position: absolute;
right: 20px;
top: 50%;
margin-top: -25px;
width: 50px;
height: 50px;
background-color: rgb(28, 180, 226);
border-radius: 50%;
}
</style>
</head>
<body>
<div class="carousel">
<ul id="list">
<li><img src="https://juejin.cn/post/images/beijing/0.jpg" ></li>
<li><img src="https://juejin.cn/post/images/beijing/1.jpg" ></li>
<li><img src="https://juejin.cn/post/images/beijing/2.jpg" ></li>
<li><img src="https://juejin.cn/post/images/beijing/3.jpg" ></li>
<li><img src="https://juejin.cn/post/images/beijing/4.jpg" ></li>
</ul>
<a href="javascript:;" class="leftbtn" id="leftbtn"></a>
<a href="javascript:;" class="rightbtn" id="rightbtn"></a>
</div>
<script>
// 得到按钮和ul,ul整体进行运动
var leftbtn = document.getElementById('leftbtn');
var rightbtn = document.getElementById('rightbtn');
var list = document.getElementById('list');
var lis = list.getElementsByTagName('li');
// 当前是第几张图显示
var idx = 0;
// 节流
var lock = true;
// 右按钮
rightbtn.onclick = function () {
// 判断节流
if (!lock) return;
lock = false;
// 还没有改idx,此时的idx这个图片就是老图,老图淡出
lis[idx].style.opacity = 0;
idx++;
if (idx > 4) idx = 0;
// 改了idx,此时的idx这个图片就是新图,新图淡入
lis[idx].style.opacity = 1;
// 动画结束之后,开锁
setTimeout(function () {
lock = true;
}, 1000);
}
// 左按钮
leftbtn.onclick = function () {
// 判断节流
if (!lock) return;
lock = false;
// 还没有改idx,此时的idx这个图片就是老图,老图淡出
lis[idx].style.opacity = 0;
idx--;
if (idx < 0) idx = 4;
// 改了idx,此时的idx这个图片就是新图,新图淡入
lis[idx].style.opacity = 1;
// 动画结束之后,开锁
setTimeout(function () {
lock = true;
}, 1000);
}
</script>
</body>
</html>
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END