面向对象的轮播图写法
// 1,面向对象编程意思,大部分内容与面向过程基本相似
// 只是将程序封装在一个对象内
// 将程序执行需要的数据,定义为对象的属性和属性值
// 将程序执行需要的代码,定义为对象的函数方法
// 优点:对象是使用{}来定义的,如果使用let 等语法定义数据等,只能在对象中使用调用,与对象外的数据不会产生冲突,不会造成全局变量污染
// 对象的数据,可以通过属性的方法获取属性值,便于调用使用
// 封装一次面向对象程序,也可以反复调用使用,不用重复定义程序代码
// 高内聚,低耦合,可反复调用
下面是代码部分
<!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,
ol,
li {
list-style: none;
}
a,
a:hover,
a:active {
text-decoration: none;
color: #333;
}
.clear::after {
content: "";
display: block;
clear: both;
}
.banner {
width: 600px;
height: 400px;
border: 3px solid #000;
margin: 40px auto;
position: relative;
overflow: hidden;
}
.banner ul {
width: 500%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
.banner ul li {
width: 600px;
height: 100%;
float: left;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
font-size: 100px;
}
.banner ol {
height: 50px;
background: rgba(0, 0, 0, .4);
position: absolute;
bottom: 50px;
left: 50%;
transform: translateX(-50%);
display: flex;
justify-content: space-evenly;
align-items: center;
border-radius: 10px;
}
.banner ol li {
width: 25px;
height: 25px;
border-radius: 50%;
background: #fff;
margin: 0 25px;
cursor: pointer;
}
.banner ol li.active {
background: red;
}
.banner div {
width: 100%;
height: 50px;
position: absolute;
top: 50%;
transform: translateY(-50%);
display: flex;
justify-content: space-between;
align-items: center;
}
.banner div a {
width: 40px;
line-height: 40px;
font-size: 40px;
font-weight: 900;
color: #fff;
background: rgba(0, 0, 0, .4);
text-align: center;
}
</style>
</head>
<body>
<div class="banner">
<!-- 需要轮序播放的图片,没有多的5和1
多出来的5和1是动态生成的
-->
<ul class="clear">
<li style="background:pink ;">img1</li>
<li style="background:gray ;">img2</li>
<li style="background:blue ;">img3</li>
<li style="background:skyblue;">img4</li>
<li style="background:orange ;">img5</li>
</ul>
<!-- 与轮播图,对应的焦点按钮
是根据轮播图的图片数量,动态生成的
-->
<ol></ol>
<div>
<a href="JavaScript:;" name="left"> < </a>
<a href="JavaScript:;" name="right"> > </a>
</div>
</div>
<script src="./04_banner.js"></script>
<script>
// 面向对象
// 只需要获取总的父级的标签对象,oDiv
// 其他的参数,都是在class类中来定义封装
const oDiv = document.querySelector('div');
// 创建实例化对象
const setLoop = new SetLoop(oDiv);
// 调用生成焦点方法
setLoop.setLi();
// 调用复制标签方法
setLoop.copyLi();
// 调用自动轮播方法
setLoop.autoLoop();
// 调用鼠标移入移出方法
setLoop.overOut();
// 调用焦点切换方法
setLoop.focus();
// 调用左右切换方法
setLoop.leftRight();
//调用解决页面隐藏的方法
setLoop.hidden();
------------------------------------------------------------------------------------------------
这里面是banne。js里面封包的一些函数。
// 面向对象,封装class类
class SetLoop{
// 定义数据参数
// 参数是 父级标签div
constructor(ele){
// 存储参数,也就是div标签对象
this.ele = ele;
// 获取设定需要的数据参数
// 获取的标签对象
this.oUl = ele.querySelector('ul');
this.oOl = ele.querySelector('ol');
this.oD = ele.querySelector('div');
this.oUllis = ele.querySelectorAll('ul li');
// 定义参数
this.index = 1;
// 存储自动轮播定时器变量
this.loopTime = 0;
// li的默认宽度
this.oLiwidth = parseInt(window.getComputedStyle(this.oUllis[0]).width );
// 定义开关变量,防止点击过快
this.bool = '原始数值';
}
// 定义方法1 , 运动函数 在其他的方法中调用
move(ele, obj, callback) {
// 1,循环
for (let type in obj) {
// 获取原始定位数据
let oldVal = parseInt(window.getComputedStyle(ele)[type]);
// 定义定时器
let time = setInterval(function () {
// 计算步长
let val = (obj[type] - oldVal) / 5;
// 判断正负,取整
val = val > 0 ? Math.ceil(val) : Math.floor(val);
// 执行步长
oldVal += val;
// 执行定位
ele.style[type] = oldVal + 'px';
// 到达目标位置,终止定时器
if (oldVal == obj[type]) {
// 终止定时器
clearInterval(time);
// 调用函数
callback()
}
}, 100)
}
}
// 定义方法2 , 设定焦点
setLi() {
// 定义变量,存储生成的li标签
let str = '';
// 根据原始轮播图,生成焦点按钮
this.oUllis.forEach(function (item, key) {
if (key == 0) {
str += `<li index="${key + 1}" class="active"></li>`;
} else {
str += `<li index="${key + 1}" ></li>`;
}
});
// 写入标签
this.oOl.innerHTML = str;
}
// 定义方法3 , 复制标签
copyLi() {
// 1,获取需要复制的标签对象
let liF = this.oUllis[0];
let liL = this.oUllis[this.oUllis.length - 1];
// 2,复制标签
let first = liF.cloneNode(true);
let last = liL.cloneNode(true);
// 3,写入标签
this.oUl.appendChild(first);
this.oUl.insertBefore(last, liF);
// 4,定义ul宽度
this.oUl.style.width = ((this.oUllis.length + 2) * this.oLiwidth) + 'px';
// 5,定义ul位移
this.oUl.style.left = -this.oLiwidth + 'px';
}
// 定义方法4,自动轮播
// 此时,所有的this,指向的都是构造函数中的参数所表示的this
// 也就是实例化对象,都要改成箭头函数
autoLoop() {
// 改成箭头函数
this.loopTime = setInterval( ()=> {
// 记录轮播次数变量++
this.index++;
// 执行运动函数,改成箭头函数
this.move(this.oUl, { left: -this.index * this.oLiwidth }, ()=>{
// 虽然写在class中的方法,可以省略function关键词
// 但是定义的还是一个函数,class语法,会自动添加 function关键词
// 有了 function关键词 就可以提前调用函数方法
// 调用时,通过 this.函数方法名称() 来调用
this.stopLoop();
})
}, 3000);
}
// 定义方法5 , 运动终止时,执行的函数
stopLoop() {
// 1,给开关变量,赋值初始值
this.bool = '原始数值';
// 2,判断idnex数值,并且给ul做定位
// 如果是最后一个img1
if (this.index == this.oUllis.length + 1) {
// 改变index数值
this.index = 1;
// 瞬间切换图片
this.oUl.style.left = (-this.index * this.oLiwidth) + 'px';
// 如果是第一个img5
} else if (this.index == 0) {
// 改变index数值
this.index = this.oUllis.length;
// 瞬间切换图片
this.oUl.style.left = (-this.index * this.oLiwidth) + 'px';
}
// 3,设定焦点按钮样式,后动
// 获取ol中的li,在生成焦点之后生成
// 在 this.ele 也就是 oDiv中 获取 ol中的li
let oOllis = this.ele.querySelectorAll('ol li');
// 循环遍历
// 使用 this.index 必须改成箭头函数
oOllis.forEach( (item) => {
// 清除所有的样式
item.className = '';
// 给点击的li,添加样式
if (item.getAttribute('index') == this.index) {
item.className = 'active';
}
})
}
// 定义方法6 , 鼠标移入移出
overOut () {
// 给父级div添加事件 oDiv改成 this.ele
// 移入清除定时器,终止函数
this.ele.addEventListener('mouseover', () =>{
clearInterval(this.loopTime)
});
// 移出,再次执行函数
this.ele.addEventListener('mouseout', () =>{
this.autoLoop();
});
}
// 定义方法7,焦点按钮切换
focus(){
// 给ol添加事件
this.oOl.addEventListener('click' , (e)=>{
// 如果点击的是li标签
if(e.target.tagName == 'LI'){
// 防止点击过快
if(this.bool !== '原始数值'){
return;
}
this.bool = '非原始数值';
// 获取点击标签,index的属性,赋值给变量
this.index = e.target.getAttribute('index')-0;
// 一定要用move()运动函数,这样才可以再次点击
this.move(this.oUl, { left: -this.index * this.oLiwidth }, ()=> {
this.stopLoop();
})
}
})
}
// 定义方法8 , 左右切换
leftRight() {
this.oD.addEventListener('click', (e)=> {
// 如果点击的是左切换
if (e.target.getAttribute('name') == 'left') {
// 防止过快
if(this.bool !== '原始数值'){
return;
}
this.bool = '非原始数值';
// index数值--
this.index--;
// 一定要用move()运动函数,这样才可以再次点击
this.move(this.oUl, { left: -this.index * this.oLiwidth }, ()=> {
this.stopLoop();
})
}else if(e.target.getAttribute('name') == 'right'){
// 防止过快
if(this.bool !== '原始数值'){
return;
}
this.bool = '非原始数值';
// index数值++
this.index++;
// 一定要用move()运动函数,这样才可以再次点击
this.move(this.oUl, { left: -this.index * this.oLiwidth }, ()=> {
this.stopLoop();
})
}
})
}
// 定义方法9 , 页面隐藏
hidden(){
// 当 页面显示变化时
// 此处是特殊的页面显示状态事件,必须是document,不能改的
document.addEventListener('visibilitychange' , ()=>{
// 如果隐藏,清除定时器,不执行自动轮播
if(document.visibilityState === 'hidden'){
clearInterval(this.loopTime);
// 如果显示,继续执行自动轮播
}else if(document.visibilityState === 'visible'){
this.autoLoop();
}
})
}
}

浙公网安备 33010602011771号