昨天被提到无缝轮播图,当时忘记怎么做的了,回来后就自己做了个小插件。勿喷,谢谢!
废话不多说直接上代码!
html
<template>
<div class="home">
<div ref="box" style="margin-top:100px;width: 300px;height: 200px"></div>
</div>
</template>
<script>
import Slideshow from '../utils/slideshow/index.js'
export default {
name: 'Home',
data() {
return {
}
},
mounted() {
let imgArr = [
require('../assets/01.jpg'),
require('../assets/02.jpg'),
require('../assets/03.jpg'),
require('../assets/04.jpg'),
]
let slideshow = new Slideshow({
imgArr,
// width:375,
// isEleDots:true,
// isBtn:true
})
slideshow.creatNode(this.$refs.box)
},
}
</script>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Tesseract</title>
</head>
</head>
<body>
<div class="box" style="margin-top:100px;width: 300px;height: 200px"></div>
</body>
<script src="./slideshow/index.js"></script>
<script type="text/javascript">
let imgArr = [
'./img/1.png',
'./img/2.png',
'./img/3.png',
'./img/4.png',
'./img/5.png',
]
let slideshow = new Slideshow({
imgArr,
// width:375,
isEleDots:true,
isBtn:true
})
slideshow.creatNode(document.getElementsByClassName('box')[0])
</script>
</html>
index.js
/**
* option : {
imgArr : Array , 图片数组
width : Number||'100%' , 容器宽度
height : Number||'100%' , 容器高度
isEleDots : Boolean , 是否显示圆点
isBtn : Boolean , 是否显示两侧按钮
color : String , 颜色
}
creatNode(node(需要插入的节点,必填))
removeEventListener() //移除所有事件
* */
export default class Slideshow {
constructor(option) {
this.imgArr = option.imgArr || [] //图片数组
this.width = option.width || '100%' //容器宽度
this.height = option.height || '100%' //容器高度
this.isEleDots = option.isEleDots || false //是否显示圆点
this.isBtn = option.isBtn || false //是否显示两侧按钮
this.color = option.color || '#f17d07' //颜色
this.TIME_DURATION = option.time || 3000 //定时器时间
this.interval = null //定时器
this.index = 0 //当前图片
this.circle = 0 //当前高亮圆点
this.eleInners = null //图片ul
this.eleDots = null //圆点ul
this.liImgs = null //装图片的li
this.liDots = null //img节点
this.elePrev = null //左边按钮
this.eleNext = null //右边边按钮
this.container = null //容器
this.LI_WIDTH = null //li宽度每次移动的距离
this.isMobile = navigator.userAgent.match(/(iPhone|iPad|Android|ios)/i) //是否位移动端
}
// 创建节点
creatNode(node) {
if (this.imgArr.length == 0) return
this.creatStyle()
this.width = this.width > node.clientWidth && this.width !== '100%' ? node.clientWidth : this.width
this.height = this.height > node.clientHeight ? node.clientHeight && this.height !== '100%' : this.height
let width = this.width != '100%' ? this.width + 'px' : node.clientWidth + 'px'
let height = this.height != '100%' ? this.height + 'px' : node.clientHeight + 'px'
let imgLis = ``
this.imgArr.forEach(item => {
imgLis += `<li style="height:${height};width:${width}">
<img src="${item}" alt="" >
</li>
`
})
let btn = `
<div id="btn-prev" class="btn-ctrl"><</div>
<div id="btn-next" class="btn-ctrl">></div>
`
let div = `
<div class="container" id="container" style="height:${height};width:${width}">
${this.isBtn ? btn : ''}
<ul id="inner-list" style="width: ${this.imgArr.length + 1}00%">
${imgLis}
</ul>
${this.isEleDots ? '<ul id="dot-list"></ul>' : ''}
</div>
`
node.innerHTML = div
this.getNode()
//首先是克隆
this.eleInners.appendChild(this.liImgs[0].cloneNode(true));
if (this.isEleDots) this.creatEleDots()
//接着定时器
this.interval = setInterval(this.autoplay.bind(this), this.TIME_DURATION)
this.bindEvent()
}
//创建样式
creatStyle() {
let styleContent = `
* {
margin: 0px;
padding: 0px
}
#container {
margin: auto;
width: 500px;
height: 500px;
position: relative;
overflow: hidden;
border-radius: 5px;
}
#inner-list {
width: 400%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
#inner-list li {
width: 500px;
height: 100%;
float: left;
}
#inner-list li img {
width: 100%;
height: 100%;
}
#dot-list {
position: absolute;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
}
#dot-list li {
float: left;
display: inline-block;
width: 20px;
height: 20px;
border-radius: 50%;
line-height: 20px;
text-align: center;
background: #ccc;
cursor: pointer;
margin-right: 10px;
}
#dot-list li.cur {
background:${this.color};
}
.btn-ctrl {
position: absolute;
cursor: pointer;
top: 50%;
font-size: 36px;
color: ${this.color};
font-weight: 500;
z-index: 2;
}
#btn-prev {
left: 0px;
}
#btn-next {
right: 0px;
}
`
let style = document.createElement('style')
style.innerHTML = styleContent
document.getElementsByTagName('head')[0].appendChild(style)
}
//接着是动画,用差值和offsetLeft值和移动的值,给一个speed让它移动
animate(obj, targetPlace) {
clearInterval(obj.timer);
obj.timer = setInterval(function () {
//判断移动的位置是向左移动还是向右移动
var speed = obj.offsetLeft > targetPlace ? -15 : 15;
var result = targetPlace - obj.offsetLeft;
//只要移动的差值大于speed,那么就一直让obj.style.left 改变
if (Math.abs(result) > Math.abs(speed)) {
obj.style.left = obj.offsetLeft + speed + 'px'
} else {
//否则如果已经移动的,obj.offsetleft与要移动的位置十分接近了,
obj.style.left = targetPlace + 'px';
clearInterval(obj.timer);
}
}, 10)
}
//向左的autoplay
autoplay() {
this.index++;
if (this.index > this.liImgs.length - 1) {
this.eleInners.style.left = 0; //赶快跳回第一张的位置
this.index = 1; //找到第二张图片
}
this.animate(this.eleInners, -this.index * this.LI_WIDTH);
if (!this.isEleDots) return
this.circle++;
if (this.circle >= this.liImgs.length - 1) {
this.circle = 0; //circle回到第一个点
}
for (var i = 0, len = this.liDots.length; i < len; i++) {
this.liDots[i].className = '';
}
this.liDots[this.circle].className = 'cur'
}
//向右移动
moveRight() {
this.index--;
if (this.index < 0) {
//赶快跳回第最后一张的位置
this.eleInners.style.left = -(this.liImgs.length - 1) * this.LI_WIDTH + 'px';
this.index = this.liImgs.length - 2; //找到倒数第二张图片
}
this.animate(this.eleInners, -this.index * this.LI_WIDTH);
if (!this.isEleDots) return
this.circle--;
if (this.circle < 0) {
this.circle = this.liImgs.length - 2; //circle回到最后一个点
}
for (var i = 0, len = this.liDots.length; i < len; i++) {
this.liDots[i].className = '';
}
this.liDots[this.circle].className = 'cur'
}
getNode() {
this.eleInners = document.getElementById('inner-list')
this.container = document.getElementById('container')
if (this.isEleDots) {
this.eleDots = document.getElementById('dot-list')
this.liDots = this.eleDots.children
}
this.liImgs = this.eleInners.getElementsByTagName('li')
this.elePrev = document.getElementById('btn-prev')
this.eleNext = document.getElementById('btn-next')
this.LI_WIDTH = this.liImgs[0].offsetWidth
}
//绑定事件
bindEvent() {
//鼠标移入,清除定时器
this.eleInners.onmouseenter = (e) => clearInterval(this.interval)
//鼠标移出,开启定时器
this.eleInners.onmouseleave = (e) => {
this.interval = setInterval(this.autoplay.bind(this), this.TIME_DURATION)
}
//圆点
if (this.isEleDots) this.eleDotsBtn()
//两侧按钮
if (this.isBtn) this.bilateralBtn()
else this.pcSlidingEvent()
if (this.isMobile) this.mobileSlidingEvent()
}
//生成小点点
creatEleDots() {
for (var i = 0, len = this.liImgs.length - 1; i < len; i++) {
var li = document.createElement('li');
this.eleDots.appendChild(li)
}
//第一个点高亮
this.liDots[0].className = 'cur'
}
//圆点事件
eleDotsBtn() {
this.eleDots.onclick = (event) => {
clearInterval(this.interval);
var target = event.target;
for (var i = 0, len = this.liDots.length; i < len; i++) {
this.liDots[i].className = '';
if (target == this.liDots[i]) {
this.circle = this.index = i
this.liDots[this.circle].className = 'cur'
}
}
this.animate(this.eleInners, -this.index * this.LI_WIDTH);
}
}
//两侧按钮
bilateralBtn() {
this.elePrev.onclick = () => {
clearInterval(this.interval)
this.moveRight();
this.interval = setInterval(this.autoplay.bind(this), this.TIME_DURATION)
}
this.eleNext.onclick = () => {
clearInterval(this.interval)
this.autoplay();
this.interval = setInterval(this.autoplay.bind(this), this.TIME_DURATION)
}
}
//移动端滑动事件
mobileSlidingEvent() {
let start, end
this.container.ontouchstart = (e) => start = e.touches[0].pageX
this.container.ontouchend = (e) => {
end = e.changedTouches[0].pageX
let direction = end - start
clearInterval(this.interval)
if (direction > 80) {
this.moveRight();
} else if (direction < -80) {
this.autoplay();
}
this.interval = setInterval(this.autoplay.bind(this), this.TIME_DURATION)
}
}
//pc滑动事件
pcSlidingEvent() {
this.container.onmousedown = (e) => {
let start = e.clientX
this.container.onmouseup = (e) => {
let end = e.clientX
let direction = end - start
clearInterval(this.interval)
if (direction > 80) {
this.moveRight();
} else if (direction < -80) {
this.autoplay();
}
//这里不能加定时器了因为鼠标离开的时候会在启动定时器
// this.interval = setInterval(this.autoplay.bind(this), this.TIME_DURATION)
}
//去掉默认拖拽事件
this.container.ondragstart = () => false
}
}
removeEventListener() {
clearInterval(this.interval)
if (this.elePrev) this.elePrev.onclick = null
if (this.eleNext) this.eleNext.onclick = null
if (this.eleDots) this.eleDots.onclick = null
this.eleInners.onmouseenter = null
this.eleInners.onmouseleave = null
this.container.ontouchstart = null
this.container.ontouchend = null
this.container.onmousedown = null
this.container.onmouseup = null
//恢复默认事件
this.container.addEventListener('ondragstart', (e) => {
e.returnValue = true
})
}
}
支持pc端移动端左右滑动
用法
option : {
imgArr : Array , 图片数组
width : Number||‘100%’ , 容器宽度
height : Number||‘100%’ , 容器高度
isEleDots : Boolean , 是否显示圆点
isBtn : Boolean , 是否显示两侧按钮
color : String , 颜色
}
然后直接 creatNode(node)方法就可以创建轮播图了