目录
效果展示:
轮播图(旋转木马)
index.html:
<style type="text/css">
*{
box-sizing: border-box;
overflow: hidden;
}
</style>
template:
<template>
<div class="outest">
<div class="before-ul" @click="user_move(-1)"><</div>
<!-- 旋转木马轮播图 -->
<ul class="content" style="left:0px" ref="ul">
<li ref="li" v-for="e of images" :key="e.id" style="transform:scale(1);opacity:0.68;zIndex:0;">
<img class="picture" :src="e.src" :alt="e.alt">
<div class="text">{{e.alt}}</div>
</li>
</ul>
<div class="after-ul" @click="user_move(1)">></div>
<!-- 底部的圆点 -->
<div>
<ul class="sub-circle">
<li ref="circle" v-for="e of images" :key="e.id"></li>
</ul>
</div>
</div>
</template>
data:
图片素材来自网络!
return{
images:[
{src:"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fss2.meipian.me%2Fusers%2F120470823%2F80cf36c23f744bdf992abb21619714dc.jpeg%3Fmeipian-raw%2Fbucket%2Fivwen%2Fkey%2FdXNlcnMvMTIwNDcwODIzLzgwY2YzNmMyM2Y3NDRiZGY5OTJhYmIyMTYxOTcxNGRjLmpwZWc%3D%2Fsign%2F41e170ae81aa27e57d5687de957d9609.jpg&refer=http%3A%2F%2Fss2.meipian.me&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1663387064&t=71853af48512807d15ee43cb3a41737a",alt:"滕王阁",id:"aaa"},
{src:"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fn.sinaimg.cn%2Fsinacn%2F20170411%2F77c8-fyeceza2014459.jpg&refer=http%3A%2F%2Fn.sinaimg.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1663387194&t=763a6f4f2f6f61606b802285fb955be8",alt:"岳阳楼",id:"bbb"},
{src:"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fnews.cnhubei.com%2Fa%2F10001%2F202202%2F536db75fa423794d829cb72eec0a0699.jpeg&refer=http%3A%2F%2Fnews.cnhubei.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1663387251&t=6a8b11f5a2c0447014185710b623a302",alt:"黄鹤楼",id:"ccc"},
{src:"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fss2.meipian.me%2Fusers%2F5738464%2F2ff02d9e5837e9702d35886742752e0f.jpg%3Fmeipian-raw%2Fbucket%2Fivwen%2Fkey%2FdXNlcnMvNTczODQ2NC8yZmYwMmQ5ZTU4MzdlOTcwMmQzNTg4Njc0Mjc1MmUwZi5qcGc%3D%2Fsign%2Fe2a10a52c511e52abe6fb5006bcc78fe.jpg&refer=http%3A%2F%2Fss2.meipian.me&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1663387424&t=420622e9f16446deee38b3171f123ea3",alt:"鹤雀楼",id:"ddd"},
{src:"https://gimg2.baidu.com/image_search/src=http%3A%2F%2F5b0988e595225.cdn.sohucs.com%2Fimages%2F20180809%2F941e123006494773931d546abc5b57b3.jpeg&refer=http%3A%2F%2F5b0988e595225.cdn.sohucs.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1663387463&t=490048000ebfcda3a1b904271d9ab81d",alt:"蓬莱阁",id:"eee"},
],
tipIndex:1, // 0-4 用于更新底部圆点 共 5个真实 li
isChanging:false, // 是否正在变换
userChanging:false, // 是否是用户触发的变换
}
methods:
moving(direction){ //控制ul移动的方法 1为 ul左移,-1为 ul右移
if(direction != 1 && direction != -1){
return;
}
this.isChanging = true; // “ 封闭式执行任务,新的任务不能打扰 ,不接新任务”
if(direction === 1){
if(this.tipIndex === 6){ //一个循环之后恢复初始化,即只有下标为 1 的li处于放大状态
this.tipIndex = 1;
this.adjust(this.tipIndex, 6, 0);
}
new Promise((res,rej)=>res(this.moveLeft())).then(val => this.tipIndex++);
}else{
if(this.tipIndex === 1){ // 先把ul整体瞬移到 以下标为6的li位于中间的位置 再进行右移
this.adjust(6, this.tipIndex, -1600);
}
new Promise((res,rej)=>res(this.moveRight())).then(val => {
if( -- this.tipIndex < 0){
this.tipIndex = 4;
}
})
}
},
moveLeft(){ // ul 向左移动
let index = this.tipIndex;
//切换底部圆点
this.$refs.circle[index%5].style.background="hsl(0,0%,90%)";
this.$refs.circle[(index+1)%5].style.background='hsl(0,0%,60%)';
let element = this.getEle('li');
element[index+1].style.zIndex='10';
element[index].style.zIndex='0';
//切换图片 t为变换次数 共32次,每隔10毫秒变换一次,依照宽度来改变,每次左移32px,320ms后移动一个li的距离
let t = 0;
let moveLeft = setInterval(()=>{
//整体移动ul
this.getEle('ul')[0].style.left = Number.parseInt(this.getEle('ul')[0].style.left) - 10 + 'px';
//下一个li放大,变清晰
element[index+1].style.transform=`scale(${1 + 0.5 / 32 * t})`;
element[index+1].style.opacity=`${0.36 + t * 0.02}`;
//当前li缩小,变模糊
element[index].style.transform=`scale(${1.5 - 0.5 / 32 * t})`;
element[index].style.opacity=`${1 - t * 0.02}`;
t++;
if(t >= 32){ //运动一个li默认的宽度之后停止定时任务
if(this.userChanging){
this.userChanging = false;
window.timer = this.defaultTimer();
}
this.isChanging = false;
clearInterval(moveLeft);
}
},10);
},
moveRight(){ // ul 向右移动
let index = this.tipIndex; //用this.tipIndex来更新圆点,用index来更新ul、li
if(index === 1){
index = 6;
}else if(index === 0){
index = 5;
}
this.$refs.circle[this.tipIndex % 5].style.background="hsl(0,0%,90%)";
this.$refs.circle[(this.tipIndex - 1 < 0) ? 4 : (this.tipIndex - 1)].style.background='hsl(0,0%,60%)';
let element = this.getEle('li');
element[index-1].style.zIndex='10';
element[index].style.zIndex='0';
//切换图片 t为变换次数 共32次,每隔10毫秒变换一次,依照宽度来改变,每次右移32px,320ms后移动一个li的距离
let t = 0;
let moveright = setInterval(()=>{
//整体移动ul
this.getEle('ul')[0].style.left = Number.parseInt(this.getEle('ul')[0].style.left) + 10 + 'px';
//上一个li放大,变清晰
element[index-1].style.transform=`scale(${1 + 0.5 / 32 * t})`;
element[index-1].style.opacity=`${0.36 + t * 0.02}`;
//当前li缩小,变模糊
element[index].style.transform=`scale(${1.5 - 0.5 / 32 * t})`;
element[index].style.opacity=`${1 - t * 0.02}`;
t++;
if(t >= 32){ //运动一个li默认的宽度之后停止定时任务
this.isChanging = false;
if(this.userChanging){
this.userChanging = false;
window.timer = this.defaultTimer();
}
clearInterval(moveright);
}
},10);
},
adjust(largeIndex, smallIndex, left){
let element = this.getEle('li');
element[largeIndex].style.transform='scale(1.5)';
element[largeIndex].style.opacity='1';
element[largeIndex].style.zIndex='10';
element[smallIndex].style.transform=`scale(1)`;
element[smallIndex].style.opacity=`0.36`;
element[smallIndex].style.zIndex='0';
this.getEle('ul')[0].style.left = left + 'px';
},
getEle(name){ //封装一个操作dom的函数
return document.getElementsByTagName(name);
},
// 调用这个函数用来给 window 添加一个 默认的定时器,
// 只有在用户主动点击切换的时候这个定时器被清除,但执行完用户的切换后又将立马加上
defaultTimer(){
return setInterval(()=>{
this.moving(1); // 参数1 是默认向左整体移动ul 即将当前li缩小,下一个li放大
},3500);
},
user_move(val){
// 如果当前 window.timer 定时器正在进行切换动作 或者 用户此前点击的切换事件正在执行,则不在执行用户此次的动作
if(this.isChanging || this.userChanging){
return;
}
clearInterval(window.timer); // 先清除默认的定时器
this.userChanging = true; // 设置用户主动进行的切换动作正在执行
this.moving(val); // 预执行
}
mounted():
//监视浏览器窗口的改变,当浏览器窗口最小化时,将默认定时器停掉,当浏览器可视时,再开启
document.addEventListener('visibilitychange',()=>{
if(document.visibilityState === 'hidden'){
clearInterval(window.timer);
}else if(document.visibilityState === 'visible'){
window.timer = this.defaultTimer();
}
})
for(let i=0; i<3; i++){ //深克隆最前面四个li放在ul的后面
let templi=this.getEle('li')[i].cloneNode(true);
this.getEle('ul')[0].appendChild(templi);
}
let element = this.getEle('li');
//初始化构造,将索引为 1 的li放大,变清晰
element[this.tipIndex].style.transform='scale(1.5)';
element[this.tipIndex].style.opacity='1';
element[this.tipIndex].style.zIndex='10';
this.$refs.circle[this.tipIndex].style.background='hsl(0,0%,60%)';
// 全局默认定时器
window.timer = this.defaultTimer();
style:
.outest{
--custom-width:960px;
--custom-height:400px;
--custom-img-number:5;
width: var(--custom-width);
height: var(--custom-height);
border-radius: 0.5rem;
border: 1px solid hsl(0, 0%, 75%);
position: relative;
}
.content{
width:calc(var(--custom-width) * --custom-img-number);
height: var(--custom-height);
padding: 0;
margin: 0;
position: absolute;
display: flex;
}
.content > li{
width: calc(var(--custom-width) / 3);
list-style: none;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background:hsl(0,0%,90%);
}
.picture{
width: 100%;
height: calc(var(--custom-height) / 2);
margin-bottom: 0.5em;
}
.text{
font-size: 1.3rem;
font-weight: 800;
text-align: center;
}
/** 向左向右按键 */
.before-ul,.after-ul{
font-size: 1.5rem;
font-weight: 900;
padding: 0.3rem;
background: hsl(0 ,0% ,80%) ;
opacity: 0.4;
z-index: 20;
position: absolute;
top: 50%;
transform: translate(0,-50%) scaleY(2);
}
.before-ul{
left:0px;
border-top-right-radius: 0.3rem;
border-bottom-right-radius: 0.3rem;
}
.after-ul{
right: 0px;
border-top-left-radius: 0.3rem;
border-bottom-left-radius: 0.3rem;
}
.before-ul:active{
color: hsl(0,90%,40%);
box-shadow: 0.5px 0.5px;
}
.after-ul:active{
color: hsl(0,90%,40%);
box-shadow: 0.5px 0.5px;
}
.before-ul:hover{
cursor: pointer;
opacity: 1;
font-weight: bolder;
}
.after-ul:hover{
cursor: pointer;
opacity: 1;
font-weight: bolder;
}
/**底部小圆圈 */
.sub-circle{
position: absolute;
left: 3%;
bottom: 20px;
display: flex;
justify-content: space-around;
padding: 0px;
margin: 0px;
z-index: 100;
}
.sub-circle > li{
list-style: none;
padding: 0.5rem;
margin: 0.1rem;
border-radius: 180px;
background: hsl(0, 0%, 90%);
}