轮播图
js
// 1,运动函数
// 参数1,标签对象
// 参数2,运动属性
// 参数3,运动终止函数
function move(ele, obj, callback) {
// 1,循环
for (var type in obj) {
// 获取原始定位数据
var oldVal = parseInt(window.getComputedStyle(ele)[type]);
// 定义定时器
var time = setInterval(function () {
// 计算步长
var 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,定义焦点按钮函数
// ol中的li标签
function setLi() {
// 定义变量,存储生成的li标签
var str = '';
// 根据原始轮播图,生成焦点按钮
oUllis.forEach(function (item, key) {
if (key == 0) {
str += `<li index="${key + 1}" class="active"></li>`;
} else {
str += `<li index="${key + 1}" ></li>`;
}
});
// 写入标签
oOl.innerHTML = str;
}
// 3,复制li标签
// 复制原始第一张轮播图到ul的最后
// 复制原始最后一张轮播图到ul的起始
function copyLi() {
// 1,获取需要复制的标签对象
var liF = oUllis[0];
var liL = oUllis[oUllis.length - 1];
// 2,复制标签
var first = liF.cloneNode(true);
var last = liL.cloneNode(true);
// 3,写入标签
oUl.appendChild(first);
oUl.insertBefore(last, liF);
// 4,定义ul宽度
oUl.style.width = ((oUllis.length + 2) * oLiwidth) + 'px';
// 5,定义ul位移
oUl.style.left = -oLiwidth + 'px';
}
// 4,自动轮播
function autoLoop() {
loopTime = setInterval(function () {
// 记录轮播次数变量++
index++;
// 执行运动函数
move(oUl, { left: -index * oLiwidth }, function () {
stopLoop();
})
}, 3000);
}
// 5,轮播停止执行函数
// 给开关变量赋值值初始值
// 判断index数值
// 设置焦点样式
function stopLoop() {
// 1,给开关变量,赋值初始值
bool = '原始数值';
// 2,判断idnex数值,并且给ul做定位
// 如果是最后一个img1
if (index == oUllis.length + 1) {
// 改变index数值
index = 1;
// 瞬间切换图片
oUl.style.left = (-index * oLiwidth) + 'px';
// 如果是第一个img5
} else if (index == 0) {
// 改变index数值
index = oUllis.length;
// 瞬间切换图片
oUl.style.left = (-index * oLiwidth) + 'px';
}
// 3,设定焦点按钮样式
// 获取ol中的li,在生成焦点之后生成
var oOllis = document.querySelectorAll('ol li');
// 循环遍历
oOllis.forEach(function (item) {
// 清除所有的样式
item.className = '';
// 给点击的li,添加样式
if (item.getAttribute('index') == index) {
item.className = 'active';
}
})
}
// 6,鼠标移入移出
// 移入终止轮播
// 移出继续轮播
function stopStart() {
// 给父级div添加事件
// 移入清除定时器,终止函数
oDiv.addEventListener('mouseover', function () {
clearInterval(loopTime)
});
// 移出,再次执行函数
oDiv.addEventListener('mouseout', function () {
autoLoop();
});
}
// 7,焦点按钮切换
function focus(){
// 给ol添加事件
oOl.addEventListener('click' , function(e){
// 如果点击的是li标签
if(e.target.tagName == 'LI'){
// 防止点击过快
if(bool !== '原始数值'){
return;
}
bool = '非原始数值';
// 获取点击标签,index的属性,赋值给变量
index = e.target.getAttribute('index')-0;
// 一定要用move()运动函数,这样才可以再次点击
move(oUl, { left: -index * oLiwidth }, function () {
stopLoop();
})
}
})
}
// 8,焦点切换
// 点左,上一张
// 点右,下一张
// 判断点击的标签
// 判断 开关变量的存储的数值
function leftRight() {
oD.addEventListener('click', function (e) {
// 如果点击的是左切换
if (e.target.getAttribute('name') == 'left') {
// 防止过快
if(bool !== '原始数值'){
return;
}
bool = '非原始数值';
// index数值--
index--;
// 一定要用move()运动函数,这样才可以再次点击
move(oUl, { left: -index * oLiwidth }, function () {
stopLoop();
})
}else if(e.target.getAttribute('name') == 'right'){
// 防止过快
if(bool !== '原始数值'){
return;
}
bool = '非原始数值';
// index数值++
index++;
// 一定要用move()运动函数,这样才可以再次点击
move(oUl, { left: -index * oLiwidth }, function () {
stopLoop();
})
}
})
}
// 9,页面隐藏
function hidden(){
// 当 页面显示变化时
document.addEventListener('visibilitychange' , function(){
// 如果隐藏,清除定时器,不执行自动轮播
if(document.visibilityState === 'hidden'){
clearInterval(loopTime);
// 如果显示,继续执行自动轮播
}else if(document.visibilityState === 'visible'){
autoLoop();
}
})
}
html
<!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>
<!--
轮播图问题说明:
1,关于ul宽度的问题
可以通过js,根据li标签个数,来设定ul宽度
可以通过css样式,来定义ul宽度
通过css样式的方法,基本都有兼容性问题,有些是无法兼容的
2,关于两个定时器的问题
move() 运动函数中,有一个定时去
autoLoop() 自动轮播函数中,也有一个定时器
首先:两个定时器,变量名称不能相同
其次:必须确保,在一个自动轮播时间周期内,可以完成运动函数
否则程序执行渲染会有错误效果
上一次的运动没有执行完,就开始执行下一次运动
等于有多个运动的定时器存在,显示会出现问题
也就是 必须 move()执行结束,再通过 autoLoop() 执行下一次move()
3,页面最小化问题
如果将页面最小化,或者后台执行页面
再次切换显示,渲染会有错误
是因为,后台时,显示不执行,但是程序执行
解决方案,是页面不显示时,清除定时器,轮播不执行
4,移入鼠标,停止轮播
当鼠标移入时,停止的是,下一次轮播
当前轮播要执行完,不会马上停止
5,焦点按钮样式的设定
方式1:当轮播图切换结束时,再改变对应的焦点按钮的样式
在运动结束调用的函数中,来定义
记录轮播次数的变量index数值,正好与我们定义的焦点标签中,属性index的数值相同的
特别注意 : 通过 getAttribute() 获取到的属性值,都是字符串类型
方式2:当轮播图一开始切换时,就首先给对应的焦点按钮,添加样式
在 autoLoop() 自动轮播函数中,执行焦点按钮样式设定
总结: 焦点样式先设定,写在 autoLoop() 函数中
焦点样式先设定,写在 loopEnd() 函数中
推荐使用后动的方式
如果是先动的方式,在 loopEnd() 函数中 index的判断,也要修改
6,鼠标移入移出的对象
当鼠标移出移出哪个对象时,执行停止轮播和执行轮播
如果使用的是 mouseover 和 mouseout 推荐使用的是最外层父级div
页面显示效果,ol是显示在ul中
但是,实际效果是ul和ol两个是平级关系
鼠标在ul上,和在ol上,实际上是在不同的标签范围内
推荐使用 父级div 添加 事件
不管是ul还是ol,都是在div中
-->
<script src="./04_banner.js"></script>
<script>
// 1,获取标签对象和设定参数
// 标签对象
var oDiv = document.querySelector('div');
var oUl = document.querySelector('ul');
var oOl = document.querySelector('ol');
var oUllis = document.querySelectorAll('ul li');
// 在 oDiv 这个标签对象中 找 div 标签
// document是在整个html文档中,查找标签
var oD = oDiv.querySelector('div');
// 参数
// 存储轮播图执行次数的变量
var index = 1;
// 存储自动轮播定时器变量
var loopTime = 0;
// li的默认宽度
var oLiwidth = parseInt(window.getComputedStyle(oUllis[0]).width );
// 定义开关变量,防止点击过快
var bool = '原始数值';
// 调用执行函数
// 设定焦点
setLi();
// 复制标签
copyLi();
// 自动轮播
autoLoop();
// 在自动轮播函数中,调用,运动终止函数
// 鼠标的移入移出
stopStart();
// 点击焦点按钮
focus();
// 左右切换
leftRight();
// 解决页面最小化问题
hidden();
// 解决点击过快问题
// 方法1:禁用标签,只有别标签,支持禁用属性
// 方法2:添加变量,判断是否是原始数值
</script>
</body>
</html>
转载请注明原文地址:https://blackberry.8miu.com/read-15265.html