初次尝试面向对象编程,轮播图,记录一下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" href="./css/resset.css">
<link rel="stylesheet" href="./css/banner.css">
</head>
<body>
<div id="app" class="banner_swiper"></div>
<script src="./js/banner.js"></script>
<script>
var list= [
{imgurl: './img/1.jpg',name: '图片1'},
{imgurl: './img/2.jpg',name: '图片2'},
{imgurl: './img/3.jpg',name: '图片3'},
{imgurl: './img/4.jpg',name: '图片4'}
]
const banner = new Banner({
app: 'app',
list: list,
srcStr: 'imgurl', // 数组中的图片地址属性
showLR: true, // 是否展示左右翻页 默认true
showIndicator: true, // 是都展示指示器 默认true
width: 1150,
height: 300
})
// console.log(banner.num)
</script>
</body>
</html>
css部分
reset.css自行百度的 补贴啦
banner.css
.banner_swiper {
position: relative;
overflow: hidden;
margin: 50px auto;
height: 244px;
}
.banner_swiper ul{
font-size: 0;
position: absolute;
left: 0;
top: 0;
bottom: 0;
/*transition: left .2s;*/
}
.banner_swiper ul li {
display: inline-block;
height: 100%;
}
.banner_swiper ul li img{
display: inline-block;
width:100%;
height:100%;
}
.indicator {
position: absolute;
bottom: 10px;
left:0;
right: 0;
height: 20px;
display: flex;
justify-content: center;
}
.indicator div {
display: inline-block;
}
.indicator div span {
display: inline-block;
width: 20px;
height: 20px;
background: white;
cursor: pointer;
border-radius: 50%;
margin: 0 10px
}
.indicator div span.active {
background: red;
}
.left_banner,.right_banner {
height: 50px;
width: 20px;
position: absolute;
top: 50%;
margin-top: -25px;
background: rgba(250,250,250,.5);
cursor: pointer;
}
.left_banner:hover,.right_banner:hover,.left_banner:active,.right_banner:active {
background: red;
color: white;
}
.left_banner {
left: 0;
}
.right_banner {
right: 0;
}
.left_banner:after,.right_banner:after {
height: 50px;
line-height: 50px;
display: inline-block;
width: 100%;
text-align: center;
font-size: 25px;
}
.right_banner:after {
content: ">";
}
.left_banner:after{
content: "<";
}
js部分
class Banner {
constructor({app,num,list,srcStr,showLR = true,showIndicator =true,width =500,height=500}) {
this.app = document.getElementById(app)
// this.ul = this.app.getElementsByTagName('ul')[0]
this.ul = null,
this.list = list
this.srcStr = srcStr
this.showLR = showLR
this.showIndicator = showIndicator
this.num = list.length // 几个轮播图
this.timer = null // 定时器
this.index = 0 // 轮播下标
this.indicatorArr = [] // 指示器数组
this.width = width
this.height = height
this.init()
}
init() { // 初始化
var that = this
this.app.style.width = this.width + 'px'
this.app.style.height = this.height + 'px'
this.createBanner()
this.cloneLastNode()
this.timer = setTimeout(function(){
that.startBanner(that.index++)
}, 2000)
if (this.showLR)this.createLR()
if (this.showIndicator) {
this.createIndicator()
this.clickIndicator()
}
}
createBanner() {
this.ul = document.createElement('ul')
for (var i =0 ; i < this.num; i ++) {
var li = document.createElement('li')
li.style.width = this.width + 'px'
var img = document.createElement('img')
img.setAttribute('src', this.list[i][this.srcStr])
li.appendChild(img)
this.ul.appendChild(li)
}
this.ul.setAttribute('id','banner')
this.ul.style.width = this.width * (this.num + 1) + 'px'
this.app.appendChild(this.ul)
}
createLR() {
var that = this
// 创建左右翻页
var leftNode = document.createElement('span')
leftNode.classList.add('left_banner')
var rightNode = document.createElement('span')
rightNode.classList.add('right_banner')
this.app.appendChild(leftNode)
this.app.appendChild(rightNode)
leftNode.addEventListener('click',function() {
that.index --
that.startBanner()
})
rightNode.addEventListener('click',function() {
that.index ++
that.startBanner()
})
}
//因为从最后一张回到第一张的时候有一个短暂空白
//所以克隆第一张图片放到最后到空白处显示第一张然后回到第一张
//因为空白时间很短暂 所以视觉上看就像回到了第一张在继续轮播
cloneLastNode() {
var cloneNode = this.ul.children[0].cloneNode(true)
this.ul.appendChild(cloneNode)
}
createIndicator() { // 生成指示器
const div = document.createElement('div')
const divBox = document.createElement('div')
divBox.setAttribute('class', 'indicator')
for (let i = 0; i < this.num;i ++) {
const span = document.createElement('span')
span.setAttribute('class', 'indicatorItem')
span.setAttribute('data-index', i)
if (i === 0) {
span.setAttribute('class', 'indicatorItem active')
}
this.indicatorArr.push(span)
div.appendChild(span)
}
divBox.appendChild(div)
this.app.appendChild(divBox)
}
// 点击指示器
clickIndicator() {
var that = this
var grandpaNode = document.getElementsByClassName('indicator')[0]
var fatherNode = grandpaNode.getElementsByTagName('div')[0]
// 使用事件委托
fatherNode.addEventListener('click',function(e) {
var event = e || window.event;
var target = event.target || event.srcElement
console.log(target.tagName)
if (target.tagName.toLocaleLowerCase() === 'span') {
var index = target.getAttribute('data-index')
that.index = index
clearTimeout(that.timer)
that.startBanner()
}
})
}
// 指示器显示
changeDot() {
for(var li = 0; li < this.indicatorArr.length; li++) {
this.indicatorArr[li].classList.remove('active')
}
if (this.index === this.indicatorArr.length) {
this.indicatorArr[0].classList.add('active')
} else {
this.indicatorArr[this.index].classList.add('active')
}
}
startBanner() { // 开始轮播
var that = this
if (this.index === this.indicatorArr.length+1) {
this.ul.style.left = 0
this.index = 1
}
if (this.index < 0) {
this.ul.style.left = -this.indicatorArr.length * 1150
this.index= this.indicatorArr.length - 1
}
if (this.showIndicator) this.changeDot()
this.animate(that.ul, {left: -that.index*that.width }, function() {
clearTimeout(that.timer)
that.timer = setTimeout(function(){
that.startBanner(that.index++)
}, 2000)
})
}
// 轮播动效果
animate(el,endObj,cd,time) {
var speedObj = {} // 速度
var startObj = {} // 开始位置
var cloneStartObj = {}
time = time ? time : 200
// 大多数电脑显示器的刷新频率是60HZ
// 大概相当于每秒钟重绘60次
// 因此,最平滑的动画效的最佳循环间隔是1000ms/60,约等于16.7ms。(16.6666666666666666666)
// 所以定时器时间间隔16.7ms
for (var key in endObj) {
startObj[key] = !!parseFloat(el.style[key]) ? parseFloat(el.style[key]) : 0
cloneStartObj[key] = startObj[key]
speedObj[key] = 16.7 * (endObj[key] - startObj[key]) / time
}
var flag = true // 为true定时器启动 false定时器未启动
var t = setInterval(function() {
for (var item in endObj) {
startObj[item] += speedObj[item]
if (endObj[item] > cloneStartObj[item] ? startObj[item] >= endObj[item] : startObj[item] <= endObj[item]) {
startObj[item] = endObj[item]
clearInterval(t)
flag = false
}
el.style[item] = startObj[item] + 'px'
if (!flag && cd) {
cd()
}
}
}, 16.7)
return t
}
}