面向对象轮播图
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
ul,
li {
list-style: none;
}
.carousel {
position: relative;
width: 600px;
height: 400px;
margin: 0 auto;
overflow: hidden;
}
ul.imgList {
position: absolute;
width: 41000px;
height: 400px;
}
ul.imgList li {
float: left;
}
.btns {
/* display: none; */
width: 600px;
height: 100px;
position: absolute;
top: 50%;
margin-top: -50px;
}
.btns .leftBtn {
float: left;
}
.btns .rightBtn {
float: right;
}
.btns span {
width: 40px;
line-height: 100px;
text-align: center;
font-size: 30px;
color: white;
cursor: pointer;
}
.cirList {
position: absolute;
bottom: 10px;
left: 140px;
right: 140px;
height: 30px;
display: flex;
justify-content: space-evenly;
}
.cirList li {
width: 20px;
height: 20px;
background-color: orange;
border-radius: 50%;
}
.cirList li.active {
background-color: red;
}
</style>
</head>
<body>
<div id="carousel" class="carousel">
<ul class="imgList">
<li><img src="images/1.jpeg" /></li>
<li><img src="images/2.jpeg" /></li>
<li><img src="images/3.jpeg" /></li>
<li><img src="images/4.jpeg" /></li>
<li><img src="images/5.jpeg" /></li>
<li><img src="images/6.jpeg" /></li>
<li><img src="images/1.jpeg" /></li>
</ul>
<div class="btns">
<span class="leftBtn"><</span>
<span class="rightBtn">></span>
</div>
<ul class="cirList">
<li class="active"></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
<script src="animate.js"></script>
<script>
// 1 获取元素
let rightBtn = document.querySelector(".rightBtn");
let leftBtn = document.querySelector(".leftBtn");
let imgList = document.querySelector('.imgList');
let listLength = imgList.getElementsByTagName("li").length;
let cirs = Array.from(document.querySelectorAll(".cirList li"));
let carousel = document.getElementById('carousel');
// 2 添加事件
// 设定一个信号量 累计鼠标点了右按钮几次
let count = 0;
// 设置一把锁
let lock = true;
let rightHandler = () => {
// 判断
if (!lock) {
return;
}
// 当为真时 下面的代码会被执行 执行过程中 应当不允许点击第二次
lock = false;
// 点一次就加一次
count++;
// 将ul元素 向左移动1个图片的距离
animate(imgList, { left: -600 * count }, 1000, () => {
// 判断是否到最后的猫腻图了
if (count >= listLength - 1) {
console.log("到了最后那张猫腻图");
// 将定位拉回0
imgList.style.left = 0;
// 将count归0
count = 0;
}
// 每次动画结束 都要开锁
lock = true;
});
change();
}
rightBtn.addEventListener("click", rightHandler);
// 左按钮点击事件
leftBtn.addEventListener("click", () => {
if (!lock) {
return;
}
lock = false;
// 当点击左按钮的时候 让count--
count--;
// 判断count是否合法
if (count < 0) {
// 修正count值
count = listLength - 1;
// 将imgList直接拽到猫腻图那
imgList.style.left = -count * 600 + "px";
count--;
}
animate(imgList, {left: count * -600}, 1000, function() {
lock = true;
});
change();
});
// 小圆点按钮 要有点击事件
cirs.forEach(function(value, index) {
value.addEventListener("click", function() {
if (!lock) {
return;
}
lock = false;
// 切换图片 其实就是让imgList运动到对应的图片 就是修改count
count = index;
animate(imgList, {left: count * -600}, 1000, function() {
lock = true;
});
// 小圆点更换样式
change();
});
});
// 封装一个函数
function change() {
// 清空所有的小圆点样式
cirs.forEach(function(value) {
value.className = "";
});
// 单独给count对应的小圆点添加
// if (count === listLength - 1) {
// cirs[0].className = "active";
// } else {
// cirs[count].className = "active";
// }
// 简化
let a = count === listLength - 1 ? 0 : count;
cirs[a].className = "active";
}
// 自动轮播
let timer = setInterval(function() {
rightHandler();
}, 10000);
// 绑定鼠标进入事件
carousel.addEventListener("mouseenter", function() {
clearInterval(timer);
console.log(leftBtn.parentNode)
leftBtn.parentNode.style.display = "block";
});
// 绑定鼠标离开事件
carousel.addEventListener("mouseleave", function() {
leftBtn.parentNode.style.display = "none";
timer = setInterval(function() {
rightHandler();
}, 10000);
});
</script>
</body>
</html>
// Banner Class
function Banner(container, arr) {
// prop: container element
this.container = container;
// prop: arr Array
this.arr = arr;
// prop: img_arr Array
this.img_arr = [];
// prop: li_ul
this.li_ul = document.createElement('ul');
// prop: cir_ul
this.cir_ul = document.createElement('ul');
// prop: btn_container
this.btn_container = document.createElement('div');
// prop: li_arr
this.li_arr = [];
// prop: cir_arr
this.cir_arr = [];
// prop: idx
this.idx = 0;
// prop: lock
this.lock = true;
this.init();
}
// Methods
Banner.prototype.init = function () {
this.create();
this.render();
this.bindEvent();
this.load();
this.changeCirStyle();
this.autoLoop();
this.bindMouseEnter();
this.bindMouseLeave();
}
// 创建元素
Banner.prototype.create = function () {
this.createBtn();
this.createList();
this.createCirs();
this.createDisguise();
}
// 创建图片列表并追加到图片UL中
Banner.prototype.createList = function () {
// 根据图片张数循环创建每一个图片li并追加到容器中
for (var i = 0; i < this.arr.length; i++) {
var li = document.createElement('li');
var img = new Image();
img.src = this.arr[i];
this.img_arr.push(img);
li.appendChild(img);
this.li_ul.appendChild(li);
this.li_arr.push(li);
}
}
// 创建左右按钮
Banner.prototype.createBtn = function () {
this.leftBtn = document.createElement('div');
this.rightBtn = document.createElement('div');
this.btn_container.appendChild(this.leftBtn);
this.btn_container.appendChild(this.rightBtn);
}
// 创建小圆点
Banner.prototype.createCirs = function () {
for (var i = 0; i < this.arr.length; i++) {
var li = document.createElement('li');
this.cir_arr.push(li);
this.cir_ul.appendChild(li);
}
}
// 渲染方法
Banner.prototype.render = function () {
this.renderBtn();
this.renderCir();
this.renderLiList();
this.renderImg();
}
Banner.prototype.renderImg = function () {
this.img_arr.forEach(value => {
value.style.width = '100%';
value.style.height = '100%';
});
}
// 渲染图片列表样式
Banner.prototype.renderLiList = function () {
// ul样式
var ulStyle = {
width: this.container.clientWidth * (this.arr.length + 1) + 'px',
height: '100%',
position: 'absolute',
top: 0,
left: 0,
listStyle: 'none'
}
for (var i in ulStyle) {
this.li_ul.style[i] = ulStyle[i];
}
// li样式
var liStyle = {
width: this.container.clientWidth + 'px',
height: this.container.clientHeight + 'px',
float: 'left'
}
this.li_arr.forEach(function (value) {
for (var i in liStyle) {
value.style[i] = liStyle[i];
}
});
}
// 渲染按钮样式
Banner.prototype.renderBtn = function () {
// 容器样式
var contaienrStyle = {
position: 'absolute',
width: '100%',
top: '50%',
height: this.container.clientHeight * 0.2 + 'px',
marginTop: -this.container.clientHeight * 0.1 + 'px',
lineHeight: this.container.clientHeight * 0.2 + 'px',
textAlign: 'center'
}
for (var i in contaienrStyle) {
this.btn_container.style[i] = contaienrStyle[i];
}
// 按钮样式
var btnStyle = {
width: this.container.clientWidth * .05 + 'px',
height: '100%',
fontSize: this.container.clientWidth * .05 + 'px',
color: 'white',
backgroundColor: '#eee3',
border: '1px solid #ccc',
boxSizing: 'border-box'
}
for (var i in btnStyle) {
this.leftBtn.style[i] = btnStyle[i];
this.rightBtn.style[i] = btnStyle[i];
}
this.leftBtn.style.float = 'left';
this.rightBtn.style.float = 'right';
this.leftBtn.style.marginLeft = '20px';
this.rightBtn.style.marginRight = '20px';
this.leftBtn.innerHTML = '<';
this.rightBtn.innerHTML = '>';
}
// 渲染小圆点样式
Banner.prototype.renderCir = function () {
var ulStyle = {
position: 'absolute',
width: this.container.clientWidth * .4 + 'px',
height: this.container.clientHeight * .15 + 'px',
bottom: '0',
left: '50%',
marginLeft: - this.container.clientWidth * .2 + 'px',
display: 'flex',
alignItems: 'center',
justifyContent: 'space-evenly'
}
for (var i in ulStyle) {
this.cir_ul.style[i] = ulStyle[i];
}
var liStyle = {
width: this.container.clientWidth * .03 + 'px',
height: this.container.clientWidth * .03 + 'px',
background: 'orange',
borderRadius: '50%',
listStyle: 'none'
}
this.cir_arr.forEach(value => {
for (var i in liStyle) {
value.style[i] = liStyle[i];
}
})
}
// 创建最后的猫腻图
Banner.prototype.createDisguise = function () {
var li = document.createElement('li');
var img = new Image();
img.src = this.arr[0];
li.appendChild(img);
this.li_ul.appendChild(li);
// li样式
var liStyle = {
width: this.container.clientWidth + 'px',
height: this.container.clientHeight + 'px',
float: 'left'
}
for (var i in liStyle) {
li.style[i] = liStyle[i];
}
img.style.width = '100%';
img.style.height = '100%';
}
// 更改小圆点的样式
Banner.prototype.changeCirStyle = function () {
this.cir_arr.forEach((value, index) => {
value.style.backgroundColor = index === this.idx ? 'pink' : 'orange';
});
}
// 挂载到树上
Banner.prototype.load = function () {
this.container.appendChild(this.li_ul)
this.container.appendChild(this.cir_ul);
this.container.appendChild(this.btn_container);
}
// 绑定事件
Banner.prototype.bindEvent = function () {
this.bindLeftBtn();
this.bindRightBtn();
this.bindCir();
}
Banner.prototype.bindLeftBtn = function () {
this.leftBtn.onclick = () => {
if (!this.lock) {
return;
}
this.lock = false;
this.idx--;
if (this.idx < 0) {
console.log(this.arr)
this.idx = this.img_arr.length;
this.li_ul.style.left = -this.idx * this.container.clientWidth + 'px'
this.idx--;
}
this.animate({ left: -this.idx * this.container.clientWidth }, 1000, () => {
this.lock = true;
this.changeCirStyle();
})
}
}
Banner.prototype.bindRightBtn = function () {
this.rightBtn.onclick = () => {
if (!this.lock) {
return;
}
this.lock = false;
this.idx++;
this.animate({ left: -this.idx * this.container.clientWidth }, 1000, () => {
if (this.idx >= this.img_arr.length) {
this.idx = 0;
this.li_ul.style.left = '0';
}
this.lock = true;
this.changeCirStyle();
})
}
}
Banner.prototype.bindCir = function () {
this.cir_arr.forEach((value, index) => {
value.onclick = () => {
if (!this.lock) {
return;
}
this.lock = false;
this.idx = index;
this.animate({left : -this.idx * this.container.clientWidth}, 1000, () => {
this.lock = true;
this.changeCirStyle();
});
}
});
}
// 动画
Banner.prototype.animate = function (styleObj, duration, callback) {
var startObj = {};
console.log(styleObj)
for (var i in styleObj) {
startObj[i] = parseInt(getCss(this.li_ul, i));
}
var interval = 20;
var allCount = duration / interval;
var count = 0;
var timer = setInterval(() => {
count++;
console.log(count)
for (var i in styleObj) {
if (i === 'opacity') {
this.li_ul.style[i] = startObj[i] + (styleObj[i] - startObj[i]) / allCount * count;
} else {
this.li_ul.style[i] = startObj[i] + (styleObj[i] - startObj[i]) / allCount * count + 'px';
}
}
if (count >= allCount) {
// 拉到终点
for (var i in styleObj) {
if (i === 'opacity') {
this.li_ul.style[i] = styleObj[i];
} else {
this.li_ul.style[i] = styleObj[i] + 'px';
}
}
// 停止定时器
clearInterval(timer);
// callback && callback();
if (callback) {
callback();
}
}
}, interval);
function getCss(dom, cssPropName) {
if (window.getComputedStyle) {
return getComputedStyle(dom)[cssPropName];
} else {
return dom.currentStyle[cssPropName]
}
}
}
// 自动轮播
Banner.prototype.autoLoop = function() {
this.timer = setInterval(() => {
this.rightBtn.onclick();
}, 2000)
}
Banner.prototype.bindMouseEnter = function(){
this.container.onmouseenter = () => {
console.log("鼠标进入")
clearInterval(this.timer);
}
}
Banner.prototype.bindMouseLeave = function() {
this.container.onmouseleave = () => {
console.log("鼠标离开")
this.autoLoop();
}
}