1.原生手写轮播图
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>轮播图</title>
<style type="text/css">
* {
padding: 0;
margin: 0;
list-style: none;
border: 0;
}
.all {
width: 500px;
height: 200px;
padding: 7px;
border: 1px solid #ccc;
margin: 100px auto;
position: relative;
}
.screen {
width: 500px;
height: 200px;
/* overflow: hidden; */
position: relative;
}
.screen li {
width: 500px;
height: 200px;
overflow: hidden;
float: left;
}
.screen ul {
position: absolute;
left: 0;
top: 0px;
width: 3000px;
/* transition: left 1s; */
}
.all ol {
position: absolute;
right: 10px;
bottom: 10px;
line-height: 20px;
text-align: center;
}
.all ol li {
float: left;
width: 20px;
height: 20px;
background: #fff;
border: 1px solid #ccc;
margin-left: 10px;
cursor: pointer;
}
.all ol li.current {
background: yellow;
}
#arr {
display: none;
}
#arr span {
width: 40px;
height: 40px;
position: absolute;
left: 5px;
top: 50%;
margin-top: -20px;
background: #000;
cursor: pointer;
line-height: 40px;
text-align: center;
font-weight: bold;
font-family: '黑体';
font-size: 30px;
color: #fff;
opacity: 0.3;
border: 1px solid #fff;
}
#arr #right {
right: 5px;
left: auto;
}
</style>
</head>
<body>
<div class="all" id="box">
<!-- 可视区域 -->
<div class="screen">
<!-- 要运动的ul标签 -->
<ul>
<li><img src="images/1.jpg" width="500" height="200" /></li>
<li><img src="images/2.jpg" width="500" height="200" /></li>
<li><img src="images/3.jpg" width="500" height="200" /></li>
<li><img src="images/4.jpg" width="500" height="200" /></li>
<li><img src="images/5.jpg" width="500" height="200" /></li>
</ul>
<ol>
<!-- 动态创建的小方块,添加在这里,样式已经给写好了-->
</ol>
</div>
<!-- 左右箭头的父盒子 -->
<div id="arr"><span id="left"><</span><span id="right">></span></div>
</div>
<script>
/*
功能分析:
- 1 小方块点击功能
- 根据ul中的图片张数进行ol中的小方块结构创建
- 给默认的第一个创建的li设置类名为 current
- 设置点击后的效果
- 按钮变色
- 设置ul的滚动
- 通过move函数设置ul的left修改
- 需要观察出每次按钮点击时要设置的ul的left值(需要观察规律)
- 规律为: - 当前按钮索引 * 图片宽度
- offsetWidth 用于获取元素的宽度
- 只读的数值类型
- 如果需要操作图片的尺寸,推荐使用可视区域的尺寸进行操作
- 2 左右按钮点击功能
- 移入移出大盒子时,设置arrBox显示隐藏
- onmouseover 鼠标移入事件
- onmouseout 鼠标移出事件
- 点击左右按钮时,设置ul进行运动
- 设置一个变量记录滚到可视区域左侧的图片张数
- ul的left规律: - 张数 * 图片宽度
- 左按钮点击,张数-1,右按钮点击,张数+1
- 设置对应小方块变色
- 观察后发现,需要设置变色的小方块的索引与count相同
- 设置左右按钮和小方块功能联动
- 注意:在小方块的点击事件中添加:将小方块的索引赋值给count
- 设置循环滚动功能
- 结构要求:需要添加假的第一张放到ul最后
- cloneNode();
- 参数为true,可以复制元素的完整结构
- 右按钮:
- 如果当前显示的为假的第一张,点击了右按钮
- 设置ul的left为0,显示出真的第一张
- 再进行正常的滚动操作
- 设置了假的第一张后,如果假的第一张显示时点击了小方块
- 会从左侧出现12345的某张图
- 修改方式:
- 在小方块点击时,检测是否为假的第一张显示
- 将ul设置left为0,将ul显示到真的第一张的位置,再进行运动
- 左按钮
- 当前如果显示真的第一张,又点击了左按钮
- 将ul抽回到假的第一张显示的位置
- 3 自动播放功能
- 实际上就是间隔一段时间(3~5s左右)进行右按钮的点击操作效果
- 间隔定时器 setInterval() clearInterval()
- 通过元素的click()进行事件的触发
- 当鼠标移动到轮播图上时,自动播放停止
- 当鼠标移出时,再次进行自动播放
- 鼠标移入移出在左右箭头显示隐藏时使用过
- 为了避免覆盖,需要使用addEventListener()
*/
// 实现:
// 1 获取元素
var box = document.getElementById('box'); // 大盒子
var screenBox = box.children[0]; // 可视区域
var imgWidth = screenBox.offsetWidth; // 获取可视区域宽度作为图片宽度使用
var ul = screenBox.children[0]; // 运动的ul
var ulLis = ul.children; // ul中的所有子元素li
var ol = screenBox.children[1]; // 小方块的父元素
var olLis = ol.children; // ol中的所有子元素li
var arrBox = box.children[1]; // 左右箭头父盒子
var arrLeft = arrBox.children[0]; // 左箭头
var arrRight = arrBox.children[1]; // 右箭头
// 2 根据ul中的图片张数创建底部小方块
for (var i = 0; i < ulLis.length; i++) {
var li = document.createElement('li');
li.innerText = i + 1;
ol.appendChild(li);
}
// 3 给创建的第一个小方块设置默认类名current
olLis[0].classList.add('current');
// 4 给小方块设置点击事件
for (i = 0; i < olLis.length; i++) {
// 给ol中每个li设置自定义属性data-index,用于保存索引
// olLis[i].setAttribute('data-index', i);
olLis[i].dataset.index = i;
olLis[i].onclick = function () {
// --- 设置假的第一张后添加的功能
if (count === ulLis.length - 1) {
ul.style.left = 0;
// count = 0; // 因为后面设置过对count的赋值,此处不需要写了
}
// 4.1 设置点击按钮变色的功能
for (var i = 0; i < olLis.length; i++) {
olLis[i].classList.remove('current');
}
this.classList.add('current');
// 4.2 设置ul根据点击的按钮进行运动
// - 需要通过自定义属性保存索引
var target = -this.dataset.index * imgWidth; // 保存目标位置
// - 通过move,让ul运动到target的位置即可
move(ul, target);
// --- 将当前元素的索引设置给count,让效果联动
count = this.dataset.index;
};
}
// ----- 左右按钮操作功能 -----
// 1 设置大盒子box移入移出时,箭头arrBox的显示隐藏
box.addEventListener('mouseover', function () {
arrBox.style.display = 'block';
});
box.addEventListener('mouseout', function () {
arrBox.style.display = 'none';
});
// 2 设置一个变量用于记录滚出去的张数
var count = 0;
// --- 克隆ul中的第一张图,放入到ul最后,设置为假的第一张
ul.appendChild(ulLis[0].cloneNode(true));
// 3 设置右按钮点击事件
arrRight.onclick = function () {
// --- 如果当前是假的第一张显示时,应当先将ul的left抽回到0,再滚动
if (count === ulLis.length - 1) {
ul.style.left = 0;
// 注意:ul的位置如果发生改变,count值要随之改变
count = 0;
}
// - 设置计数+1
count++;
// - 根据count设置ul的运动位置
var target = -count * imgWidth;
move(ul, target);
// - 设置按钮变色
for (var i = 0; i < olLis.length; i++) {
olLis[i].classList.remove('current');
}
// 设置了假的第一张后,假的第一张显示时应当为按钮1高亮
if (count === ulLis.length - 1) {
olLis[0].classList.add('current');
} else {
olLis[count].classList.add('current');
}
};
// 4 设置左按钮点击事件
arrLeft.onclick = function () {
// 检测当前是否显示第一张
if (count === 0) {
ul.style.left = -(ulLis.length - 1) * imgWidth + 'px';
count = ulLis.length - 1; // 将count更新
}
// 基本滚动操作
count--;
var target = -count * imgWidth;
move(ul, target);
for (var i = 0; i < olLis.length; i++) {
olLis[i].classList.remove('current');
}
olLis[count].classList.add('current');
};
// --- 自动播放功能
// 1 设置定时器,进行自动播放
var timer = setInterval(function () {
// 2 调用右按钮的点击事件, 通过click()操作
arrRight.click();
}, 3000);
// 3 鼠标移入时,设置自动播放停止
// - 需要给box重复设置onmouseover和onmouseout
box.addEventListener('mouseover', function () {
clearInterval(timer);
});
box.addEventListener('mouseout', function () {
// 重新开启时,必须设置给timer,而且必须是全局变量
timer = setInterval(function () {
arrRight.click();
}, 3000);
});
/* move函数用于让某个元素移动到指定位置
- element 是要运动的元素,DOM对象,别写id名或标签名之类的东西
- target 是目标位置,数值类型
*/
function move(element, target) {
// 为了避免元素出现抖动
clearInterval(element.timer);
// 设置新运动的定时器操作:
element.timer = setInterval(function () {
// 1 获取元素当前的位置
var current = element.offsetLeft;
// 2 计算每次要运动的距离(步长)
var step = (target - current) / 10;
// 对step计算的结果进行取整,确保至少移动1px
// - 根据step的正负设置对应的向上或向下取整操作
step = step > 0 ? Math.ceil(step) : Math.floor(step);
// 3 计算新的运动位置
current += step;
// 4 设置给元素的left进行运动
element.style.left = current + 'px';
// 5 当元素运动到目标位置后,清除定时器
if (current === target) {
clearInterval(element.timer);
}
}, 20);
}
</script>
</body>
</html>