直接上代码先看效果,不依赖任何库,需要的直接复制这个swiper类就可以了,结构可以继续嵌套,样式可以自行修改!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<title>滚动轮播插件</title>
</head>
<style>
html,body{
padding: 0;
margin: 0;
width: 100%;
}
li{
list-style:none;
}
div,ul,li{
box-sizing: border-box;
margin: 0;
padding: 0;
}
.scroll{
padding: 20px;
height: 140px;
}
.swiper{
overflow: hidden;
width: 100%;
height: 100%;
/*padding: 10px;*/
position: relative;
}
.swiperUl{
height: 100%;
}
.leftBtn,.rightBtn{
position: absolute;
top: 50%;
transform: translateY(-50%);
}
.leftBtn{
left: 10px;
}
.rightBtn{
right: 10px;
}
.swiperUl li{
float: left;
width: 120px;
height: 120px;
background-color: skyblue;
}
</style>
<body>
<!--Dom结构-->
<div class="scroll">
<div class='swiper' id='swiper'>
<ul class='swiperUl'>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
</ul>
<div class='leftBtn'><</div>
<!--左右箭头可以自己放置icon或者图片,不需要左右箭头的直接注释,当然,左右轮播就不会生效了-->
<div class='rightBtn'>></div>
</div>
</div>
</body>
<script>
class Swiper{//li只能设置padding
constructor(result){//result是使用插件时传导过来的参数
this.element = result.element;//容器元素
this.step = result.step;
this.distance = result.distance;
this.number = result.number;
this.ul = null;
this.list = null;//所有的li
this.liWidth = 0;//li的长度
this.scrollMax = 0;
this.startX = 0;
this.moveX = 0;
this.offsetX = 0;
this.swiperNow = 0;//ul的位置(初始是0,后面累加)
this.alginOffset = 0;//
this.leftBtn = null;//左箭头
this.rightBtn = null;//右箭头
this.init();
}
init(){//初始方法
let that = this;
let swiper = document.getElementById(this.element);
let swiperWidth = swiper.clientWidth;
this.ul = swiper.children[0];
this.list = this.ul.children;
if(this.number){//number存在就有插件动态设置宽度,否则就是使用者自己设置
this.liWidth = swiperWidth/this.number;
for(let i=0;i<this.list.length;i++){
this.list[i].style.width = this.liWidth + "px"
}
}else{
this.liWidth = this.list[0].clientWidth;//li的长度
}
this.ul.style.width = this.liWidth*this.list.length + 'px';///设置Ul的长度
this.scrollMax = this.ul.clientWidth - swiperWidth;//最大能滑动的距离
// 监听事件
swiper.addEventListener('touchstart', function (e) {
this.startX =e.targetTouches[0].clientX;
}.bind(that))
swiper.addEventListener('touchmove', function (e) {
this.moveX = e.targetTouches[0].clientX;//现在滚动到的距离
//手指的偏移量:
if(this.alginOffset){//是否是每次的初始滑动
this.offsetX = this.moveX - this.alginOffset;//实际滑动的距离=现在的点-上一次的点
}else{
this.offsetX = this.moveX - this.startX
}
this.alginOffset = this.moveX;//上一次滑动到的点的位置
if(this.scrollMax<=0){//如果当前ul总长还不超过外面显示的盒子,那么就不能滑动
return
}
if(this.offsetX < 0){
//手指右滑
this.swiperNow+=(this.offsetX*1.5);//控制滑动的倍数
if(Math.abs(this.swiperNow)>this.scrollMax){
this.swiperNow = -this.scrollMax
}
this.ul.style.transform = "translateX(" + this.swiperNow + "px)";
}else if(this.offsetX > 0){
//手指左滑
this.swiperNow+=(this.offsetX*1.5);//控制滑动的倍数
if(this.swiperNow>0){
this.swiperNow = 0;
}
this.ul.style.transform = "translateX(" + this.swiperNow + "px)";
}
}.bind(that))
swiper.addEventListener('touchend', function (e) {
//结束滑动,要清除之前记录的上一次滚动距离
this.alginOffset = 0;
}.bind(that))
if(swiper.children[1]){
this.leftBtn = swiper.children[1];
this.leftBtn.addEventListener('click',this.leftBtnClick.bind(that));
}
if(swiper.children[2]){
this.rightBtn = swiper.children[2];
this.rightBtn.addEventListener('click',this.rightBtnClick.bind(that));
}
}
leftBtnClick(){
if(this.scrollMax<=0){
return;
}
let startPos = this.swiperNow;
//做一个处理:必须要让轮播滚动为li的整倍数(就会显示3个Li)
this.swiperNow = (Math.floor(this.swiperNow/this.liWidth)+this.step)*this.liWidth;//计算当前是第几个Li,然后移动3个
if(this.swiperNow>0){
this.swiperNow = 0;
}
this.animate.call(this,this.ul,startPos,this.swiperNow);
}
rightBtnClick(){
if(this.scrollMax<=0){
return;
}
let starPos = this.swiperNow;
this.swiperNow = (Math.ceil(this.swiperNow/this.liWidth)-this.step)*this.liWidth;//计算当前是第几个Li,然后移动3个
if(Math.abs(this.swiperNow)>this.scrollMax){
this.swiperNow = -this.scrollMax
}
this.animate.call(this,this.ul,starPos,this.swiperNow);
}
animate(element,swiperNow, target) {
//元素,元素当前位置,需要去的目标位置
//这个元素只能有一个定时器
let distance = this.distance;
clearInterval(element.timerId);
//给这个元素设置定时器
element.timerId = setInterval(function () {
//步进值
let step =distance;
// swiperNow;//当前位置
//若当前位置的距离大于目标位置的距离 step应该是-10
if (swiperNow > target) {//0,-350
step = -step;
}
swiperNow += step;
//停止
if (Math.abs(swiperNow - target) <= Math.abs(step)) {
swiperNow = target;
clearInterval(element.timerId);
element.style.transform = "translateX(" + swiperNow + "px)";
return;
}
element.style.transform = "translateX(" + swiperNow + "px)";
}, 16)
}
}
</script>
<script>
new Swiper({
element:'swiper',//容器
step:1,//一次滚动几个li
distance:20,//每16毫秒滚动的像素(每帧滚动像素值)
number:3,//一页几个li,如果需要自己设置大小,可以不传或者传个0
})
</script>
</html>