节流就是n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效。
HTML5层面首先需要有两层外部盒子包裹最里面的那层滚动层,比如:
<div>
<ul>
<li></li>
</ul>
</div>
然后添加两个按钮,用做点击向左向右滑动
CSS3层面
最外层div设置溢出隐藏,重点:中间ul宽度设置为无限长或者远远大于使用宽度(如7000px),
li通过浮动或flex布局使其并排显示,其余自由设置。
JS层面
克隆前面几个li(此处随意,如果让显示五张图滑动的话,就克隆前面四个li。总之想要n张图显示则克隆前面n-1个li)。定义两个变量,分别表示最后一张图片和当前图片,设置一个节流默认状态true。点击右按钮使ul向右滑动,点击时判断节流状态,true则继续执行,false则return,节流状态改为false,添加transition过渡然后向右移动xx像素,判断当前图片是否时最后一张,是则就瞬间变为第一张,这里需要注意去掉过渡是使用延时器,延时器时间为设置过渡时间的一半。延时过渡设置的时间把节流改为true点击左按钮与右按钮逻辑一样。注意一点,及当此时为第一张图片时,要瞬间移动到最后一张去掉过渡,使transform设为最后一张的位置,然后设置延时器延时时间为0,在延时器里瞬间加上过渡和动画。设置一个定时器,然后给最外层div加上鼠标事件,移入时清除定时器,移出时开启,无缝轮播就完成啦!
附上完整代码:
<!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>
<style>
* {
margin: 0;
padding: 0;
}
.content_right{
position: relative;
width:1200px;
height: 200px;
overflow: hidden;
margin: 0 auto;
border: 1px solid #000;
}
.content_right ul{
display: flex;
align-items: center;
width:7000px;
height: 200px;
}
.content_right ul li{
display: flex;
justify-content: center;
align-items: center;
width: 180px;
height: 180px;
margin-left: 50px;
background-image: linear-gradient(to bottom right, #43aeff,#6c7dff, #a339ff);
color: #ffffff;
}
.content_right ul li img{
width: 60px;
height: 60px;
}
.btn_left{
position: absolute;
width: 60px;
height: 60px;
line-height: 60px;
font-size: 42px;
text-align: center;
margin: 60px 0 0 0px;
color: #ffffff;
background: #8f00b3;
opacity: 0;
border-radius: 50%;
cursor: pointer;
z-index: 111;
}
.btn_right{
position: absolute;
width: 60px;
height: 60px;
line-height: 60px;
font-size: 42px;
text-align: center;
right: 0;
margin: 60px 0px 0 0;
color: #ffffff;
background: #8f00b3;
opacity: 0;
border-radius: 50%;
cursor: pointer;
z-index: 111;
}
.content_right:hover .btn_left,.content_right:hover .btn_right{
opacity: .6;
}
</style>
</head>
<body>
<div class="content_right" id="root" >
<div class="btn_left btn" id="left_btn" ><</div>
<div class="btn_right btn" id="right_btn">></div>
<ul ref="enterpriseList" id="list">
<li><img src="./imges/default.png" alt="">1</li>
<li><img src="./imges/default.png" alt="">2</li>
<li><img src="./imges/default.png" alt="">3</li>
<li><img src="./imges/default.png" alt="">4</li>
<li><img src="./imges/default.png" alt="">5</li>
<li><img src="./imges/default.png" alt="">6</li>
<li><img src="./imges/default.png" alt="">7</li>
</ul>
</div>
</body>
<script>
//获取标签
const root = document.getElementById('root');
const left_btn = document.getElementById('left_btn');
const right_btn = document.getElementById('right_btn');
const list = document.getElementById('list');
const circles_li = list.getElementsByTagName('li');
// 克隆前面四个li
const clone_list = circles_li[0].cloneNode(true);
const clone_list1 = circles_li[1].cloneNode(true);
const clone_list2 = circles_li[2].cloneNode(true);
const clone_list3 = circles_li[3].cloneNode(true);
list.appendChild(clone_list);
list.appendChild(clone_list1);
list.appendChild(clone_list2);
list.appendChild(clone_list3);
//设定最后一张图片
len=circles_li.length-5
//记录当前图片位置
idx=Math.trunc(len/2)
//设置函数节流
let lock = true;
// 右按钮
right_btn.onclick = right_btn_handler;
function right_btn_handler() {
//点击右按钮判断节流锁状态
if (!lock) return;
// 关锁
lock = false;
// 加上过渡
list.style.transition = 'transform .5s ease 0s';
idx++;
list.style.transform = 'translateX(' + -230 * idx + 'px)';
//判断当前图片是否时最后一张,是则就瞬间变为第一张
if (idx > len) {
setTimeout(() => {
//去掉过度
list.style.transition = 'none'
// 删除transform属性
list.style.transform = 'none'
idx = 0;
}, 250);
}
//开锁
setTimeout(() => {
lock = true;
}, 500);
};
// 左按钮
left_btn.onclick= function() {
//点击左按钮判断节流锁状态
if (!lock) return;
// 关锁
lock = false;
if (idx == 0) {
//去掉过度
list.style.transition = 'none'
//当此时为第一张图时,瞬间变为最后一张图
list.style.transform = 'translateX(' + -230 * len + 'px)';
idx = len;
// 让瞬间移动过后,再把过渡加上
setTimeout(() => {
// 加上过渡
list.style.transition = 'transform .5s ease 0s';
//动画
list.style.transform = 'translateX(' + -230 * len + 'px)';
}, 0);
} else {
idx--;
list.style.transform = 'translateX(' + -230 * idx + 'px)';
}
//开锁
setTimeout(() => {
lock = true;
}, 500);
};
let timer = setInterval(() => {
right_btn_handler();
}, 2000);
//鼠标进入轮播图,停止自动轮播
root.onmouseenter = function() {
// 清除定时器
clearInterval(timer);
};
//鼠标离开轮播图,开始自动轮播
root.onmouseleave = function() {
// 设表先关
clearInterval(timer);
// 设置定时器
timer = setInterval(() => {
right_btn_handler();
}, 1500);
}
</script>
</html>
vue3实现
<template>
<!-- 入驻企业-->
<div class="partner">
<div class="title_box">
<div class="div">
<div class="icon_box">
</div>
<div class="margin20">
合作伙伴
</div>
<div class="icon_box">
</div>
</div>
</div>
<div class="content_right" @mouseenter="onmouseenter" @mouseleave="onmouseleave">
<div class="btn_left" @click="toLeft"><i class="iconfont"></i></div>
<div class="btn_right" @click="toRight"><i class="iconfont"></i></div>
<ul ref="enterpriseList" >
<li v-for="(item,index) in data" :key="index">
<img
:src="urlIp+item.EnterpriseLogo"
onerror="javascript:this.src='/images/icon09.png';"
alt="logo">
<p>{{item.EnterpriseName}}</p>
</li>
</ul>
</div>
</div>
</template>
<script>
import router from '@/router/index'
import {ref, reactive,toRefs, onMounted, nextTick } from 'vue'
import store from '@/store/index'
import {GET} from '@/request/api'
export default {
name: "partner",
props: {
},
setup(props) {
const urlIp=store.state.imageUrl
const Data=reactive({
data:[]
});
let len=0
let idx = 0;
//获取入驻企业
GET('DataService.asmx/GetEnterpriseListByCount',{count:'10'}).then((res)=>{
Data.data=res.Data
Data.data.push(res.Data[0])
Data.data.push(res.Data[1])
Data.data.push(res.Data[2])
Data.data.push(res.Data[3])
len=Data.data.length-5
idx=Math.trunc(len/2)
enterpriseList.value.style.transform = 'translateX(' + -230 * idx + 'px)';
})
const enterpriseList=ref(null)
//设置函数节流
let lock = true;
// 右按钮
const toRight = right_btn_handler;
function right_btn_handler() {
//点击右按钮判断节流锁状态
if (!lock) return;
// 关锁
lock = false;
// 加上过渡
enterpriseList.value.style.transition = 'transform .5s ease 0s';
idx++;
enterpriseList.value.style.transform = 'translateX(' + -230 * idx + 'px)';
//判断当前图片是否时最后一张,是则就瞬间变为第一张
if (idx > len) {
setTimeout(() => {
//去掉过度
enterpriseList.value.style.transition = 'none'
// 删除transform属性
enterpriseList.value.style.transform = 'none'
idx = 0;
}, 250);
}
//开锁
setTimeout(() => {
lock = true;
}, 500);
};
// 左按钮
const toLeft= function() {
//点击左按钮判断节流锁状态
if (!lock) return;
// 关锁
lock = false;
if (idx == 0) {
//去掉过度
enterpriseList.value.style.transition = 'none'
//当此时为第一张图时,瞬间变为最后一张图
enterpriseList.value.style.transform = 'translateX(' + -230 * len + 'px)';
idx = len;
// 让瞬间移动过后,再把过渡加上
setTimeout(() => {
// 加上过渡
enterpriseList.value.style.transition = 'transform .5s ease 0s';
//动画
enterpriseList.value.style.transform = 'translateX(' + -230 * len + 'px)';
}, 0);
} else {
idx--;
enterpriseList.value.style.transform = 'translateX(' + -230 * idx + 'px)';
}
//开锁
setTimeout(() => {
lock = true;
}, 500);
};
let timer = setInterval(() => {
right_btn_handler();
}, 2000);
//鼠标进入轮播图,停止自动轮播
onmouseenter = function() {
// 清除定时器
clearInterval(timer);
};
//鼠标离开轮播图,开始自动轮播
onmouseleave = function() {
// 设表先关
clearInterval(timer);
// 设置定时器
timer = setInterval(() => {
right_btn_handler();
}, 1500);
}
//查看详情
const getDetails=()=>{
}
return{
...toRefs(Data),
getDetails,
enterpriseList,
toLeft,
toRight,
onmouseenter,
onmouseleave,
urlIp
}
}
};
</script>
<style scoped lang="scss">
.partner{
width: 1200px;
height: 300px;
margin: 0 auto 30px auto;
}
.title_box{
height: 100px;
margin: 0 auto;
}
.div{
display: flex;
justify-content: center;
}
.margin20{
margin: 20px 20px;
font-size: 28px;
color: #19308d;
font-weight: bold;
}
// 左右小图标
.icon_box{
width: 8px;
height: 8px;
border-radius: 50%;
background: #19308d;
margin-top: 35px;
}
.content_right{
position: relative;
width:1200px;
height: 200px;
overflow: hidden;
}
.content_right ul{
display: flex;
align-items: center;
width:7000px;
height: 200px;
}
.content_right ul li{
width: 180px;
height: 180px;
margin-left: 50px;
background-image: linear-gradient(to bottom right, #43aeff,#6c7dff, #a339ff);
color: #ffffff;
}
.content_right ul li p{
font-size: 14px;
margin-top: 10px;
}
.content_right ul li img{
width: 60px;
height: 60px;
margin-top: 40px;
}
.btn_left{
position: absolute;
width: 60px;
height: 60px;
line-height: 60px;
margin: 60px 0 0 120px;
color: #279af6;
background: #ffffff;
opacity: 0;
border-radius: 50%;
cursor: pointer;
z-index: 111;
}
.btn_right{
position: absolute;
width: 60px;
height: 60px;
line-height: 60px;
right: 0;
margin: 60px 120px 0 0;
color: #279af6;
background: #ffffff;
opacity: 0;
border-radius: 50%;
cursor: pointer;
z-index: 111;
}
.content_right:hover .btn_left,.content_right:hover .btn_right{
opacity: .6;
}
</style>