<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
list-style: none;
border: 0;
}
.all {
width: 500px;
height: 300px;
margin: 100px auto;
padding: 7px;
border: 1px solid #ccc;
position: relative;
}
.screen {
width: 500px;
height: 300px;
position: relative;
overflow: hidden;
}
.screen ul {
position: absolute;
left: 0;
top: 0px;
width: 3000px;
}
.screen li {
width: 500px;
height: 300px;
overflow: hidden;
float: left;
}
.screen ol {
/*width: 50%;
height: 30px;*/
position: absolute;
bottom: 7px;
right: 7px;
}
.screen ol li {
width: 30px;
height: 30px;
line-height: 30px;
background-color: #fff;
margin: 0 1px;
text-align: center;
cursor: pointer;
}
.screen ol li.current {
background-color: yellow;
}
#slider {
text-align: center;
font-weight: bold;
font-family: '黑体';
font-size: 30px;
color: #fff;
display: none;
z-index: 1000;
}
#prev, #next{
position: absolute;
top: 50%;
transform: translateY(-50%);
background-color: rgba(0, 0, 0, 0.3);
width: 30px;
height: 30px;
line-height: 30px;
cursor: pointer;
}
#prev {
left: 0;
}
#next {
right: 0;
}
</style>
</head>
<body>
<div id="box" class="all">
<div class="screen">
<ul>
<li><img src="images/banner1.jpg" alt=""></li>
<li><img src="images/banner2.jpg" alt=""></li>
<li><img src="images/banner3.jpg" alt=""></li>
</ul>
<ol></ol>
</div>
<div id="slider">
<div id="prev"><</div>
<div id="next">></div>
</div>
</div>
<script src="js/common.js"></script>
<script src="js/animate.js"></script>
<script>
// 获取元素
var box = my$('box');
var screen = box.children[0];
var ul = screen.children[0];
var ol = screen.children[1];
//箭头
var slider = my$('slider');
var prev = my$('prev');
var next = my$('next');
// 图片的宽度
var imgWidth = screen.offsetWidth;
// 动态生成序号
var liNums = ul.children.length;
for (var i = 0; i < liNums; i++) {
var li = document.createElement('li');
// 给li设置自定义索引 标签中自定义属性值为字符串形式
li.setAttribute('index', i);
ol.appendChild(li);
setInnerText(li, i + 1);
// if (i === 0) {
// li.className = 'current';
// }
// 点击ol序号,动态切换图片,点击2,图片向左走过1张图片的宽度
li.onclick = liClick;
}
function liClick() {
// 所有li不高亮显示
for(var i = 0; i < ol.children.length; i++) {
var li = ol.children[i];
li.className = '';
}
// 当前点击li高亮显示
this.className = 'current';
// 动态切换图片,点击2,图片向左走过1张图片的宽度
// console.log(li.getAttribute('index')); // 字符串类型
// 获取自定义属性
var liIndex = parseInt(this.getAttribute('index'));
animation(ul, -imgWidth * liIndex);
// 让全局index和liIndex保持一致 否则在点击最后一张图片对应的序号后再点击next按钮,2会高亮显示,因为没有改变163行的全局index值
index = liIndex;
}
// 让序号0高亮显示
ol.children[0].className = 'current';
// 鼠标放在图片上显示上一页 上下页
box.onmouseenter = function () {
slider.style.display = 'block';
// 清除定时器
clearInterval(timerId);
}
box.onmouseleave = function () {
slider.style.display = 'none';
// 鼠标离开 继续执行自动播放
timerId = setInterval(function () {
next.click();
}, 2000);
}
// 上一页 上下页功能实现
var index = 0;
next.onclick = function () {
// 判断是否是克隆的第一张图片,如果是,修改ul的坐标,显示真正的第一张图片
if (index === liNums) {
ul.style.left = '0px';
index = 0;
}
index++;
// if (index < liNums - 1) {
if (index < liNums) { // 克隆后ul中的li个数多1,点击到最后一张图片的时候还要继续向后走 liNums - 1改为liNums,克隆的图片没有对应的序号,无法执行click(),故将index++;移到if外面
// animation(ul, -index * imgWidth); // for遍历去除所有li的高亮 再找到当前点击的index所属的li比较麻烦。点击下一页时,相当于直接点击对应的ol的li,简便方法:用click()模拟人手点击事件
ol.children[index].click();
} else {
// 所有li不高亮显示
for(var i = 0; i < ol.children.length; i++) {
var li = ol.children[i];
li.className = '';
}
// 当前点击li高亮显示
ol.children[0].className = 'current';
animation(ul, -imgWidth * index);
}
}
prev.onclick = function () {
// if (index > 0) {
// index--;
// // animation(ul, -index * imgWidth);
// ol.children[index].click();
// }
// 图片是第一张的时候,偷偷地将末尾克隆的图片置于可视区域
if (index === 0) {
index = liNums;
ul.style.left = - index * imgWidth + 'px';
}
index-- ;
ol.children[index].click();
}
// 无缝滚动
// 在最后一张图片的后面克隆第一张图片
var firstLi = ul.children[0];
var cloneLi = firstLi.cloneNode(true); // true克隆连带内容 false的时候不带内容,默认为false
ul.appendChild(cloneLi);
// 自动播放
var timerId = setInterval(function () {
next.click();
}, 2000);
</script>
</body>
</html>
common.js:
// 通过id获取元素
function my$(element) {
var el = document.getElementById(element);
return el;
}
// innerText textContent 兼容性处理
function setInnerText(element, content) {
if (typeof element.innerText === 'string') {
element.innerText = content;
} else {
element.textContent = content;
}
}
animate.js:
// 动画封装
// var timerId = null; // 需全局变量
function animation(element, target) {
// 给每个element增加一个属性timerId,保证定时器标志互不干扰
if (element.timerId) {
clearInterval(element.timerId);
element.timerId = null;
}
element.timerId = setInterval(function () {
// 步距
var step = 10;
var current = element.offsetLeft;
// 如果当前位置 > 目标位置 step < 0
if (current > target) {
step = -Math.abs(step);
}
// 当前位置和目标位置的差值小于step
// console.log(Math.abs(current - target));
// console.log(Math.abs(step));
if (Math.abs(current - target) <= Math.abs(step)) {
// 停止定时器
clearInterval(element.timerId);
element.style.left = target + 'px'; // 赋值为目标值
// 退出函数
return;
};
// 移动盒子
current += step;
element.style.left = current + 'px';
}, 30);
}