js轮播图改进版
在肝前端大作业时,产生了使用轮播图的想法,翻阅了之前自己发过的一篇帖子,发现完全不能满足现在的需求,发现csdn上一篇帖子的代码写的不错,于是摘录下来学习
实现的效果:
- 自动播放
- 鼠标停留时停止播放,显示左右切换
- 点击左右切换、下方圆形可以手动切换
- 图片无缝切换,首位切换无违和感
采用胶片播放方式来切换图片
经过css修饰后
html部分
<!DOCTYPE html>
<head>
</head>
<body>
<div id="box">
<div id="slider">
<ul class="slieder-item-container">
<li>
<a href="#"><img src="img/index1.jpg" /></a>
</li>
<li>
<a href="#"><img src="img/index2.jpg" /></a>
</li>
<li>
<a href="#"><img src="img/index3.jpg" /></a>
</li>
</ul>
<div class="arrow-container">
<span class="left-arrow"><</span>
<span class="right-arrow">></span>
<!-- 这个是左右箭头,用于切换图片 -->
</div>
<div class="indicator-container">
<span class="indicator active"></span>
<span class="indicator"></span>
<span class="indicator"></span>
<!-- 这个是图片下方的小圆点,定位第几张图 -->
</div>
</div>
</body>
css部分
#slider,
#slider ul,
#slider ul li a {
width: 800px;
height: 400px;
margin: 0;
padding: 0;
}
#slider {
position: absolute;
/* position: relative; */
border: 2px solid black;
/*padding: 3px;*/
margin: 10px 0 0 10px;
/* z-index: 1; */
overflow: hidden;
/* 隐藏显示区域外的图片 */
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
#slider ul {
position: absolute;
list-style-type: none;
width: 6000px;
/* 设置图片列表的长度 */
/*transition-duration: 0.3s;*/
}
#slider li {
float: left;
}
#slider a {
/* display: inline-block; */
display: block;
}
img {
width: 100%;
height: 100%;
}
#slider:hover .arrow-container {
display: block;
}
.arrow-container {
position: absolute;
width: 100%;
height: 50px;
top: 50%;
margin-top: -25px;
display: none;
}
/* 箭头的样式设计 */
.arrow-container span {
position: absolute;
width: 50px;
height: 50px;
font-size: 40px;
/*display: inline-block;*/
text-align: center;
line-height: 50px;
background: rgba(0, 0, 0, 0.2);
color: white;
}
.left-arrow {
left: 0px;
cursor: pointer;
}
.right-arrow {
right: 0px;
cursor: pointer;
}
/* 小圆点的样式设计 */
.indicator-container {
position: absolute;
width: 150px;
height: 30px;
line-height: 30px;
bottom: 0;
left: 50%;
margin-left: -75px;
text-align: center;
}
.indicator {
display: inline-block;
width: 15px;
height: 15px;
border-radius: 100%;
background: white;
cursor: pointer;
}
.indicator.active {
background: lightskyblue;
}
js部分
var autoplay = true;
var autoplay_Delay = 2000; // ms
var autoplayId;
var intervalId;
var slider;
var slider_item_container;
var slider_items;
var indicator_container;
var slider_item_width;
var curIndex = 0;
window.onload = function() {
initElement();
initEvent();
if (autoplay) {
startAnimation(slider_item_container);
}
}
// 初始化元素
function initElement() {
slider = document.getElementById("slider");
slider_items = slider.getElementsByTagName("li");
slider_item_container = slider.getElementsByClassName("slieder-item-container")[0];
indicator_container = slider.getElementsByClassName("indicator-container")[0];
var firstItem = slider_items[0].cloneNode(true);
slider_item_container.appendChild(firstItem);
slider_item_width = slider_items[0].offsetWidth;
}
// 初始化相关事件
function initEvent() {
slider.addEventListener("mouseover", function () {
clearTimeout(autoplayId);
autoplay = false;
});
slider.addEventListener("mouseout", function () {
autoplay = true;
startAnimation(slider_item_container);
});
var indicators = indicator_container.children;
for (var i = 0; i < indicators.length; i++) {
indicators[i].setAttribute("index", i);
indicators[i].addEventListener("click", function () {
var index = parseInt(this.getAttribute("index"));
next(index);
});
}
var left_arrow = slider.getElementsByClassName("left-arrow")[0];
var right_arrow = slider.getElementsByClassName("right-arrow")[0];
left_arrow.addEventListener("click", function () {
prev();
});
right_arrow.addEventListener("click", function () {
next();
});
}
// 动画效果,传入的形参未要移动的元素以及移动的目标值
// 默认每10ms移动10px,手动翻页时,移动事件缩短,每次移动step值增大
function animate(element, target) {
var step = 10;
var time = 10;
var gap = (Math.abs(target - element.offsetLeft) / slider_item_width);
if (gap > 1) {
step = step * gap;
time = time / gap;
}
if (element) {
step = (element.offsetLeft > target) ? -step : step;
clearInterval(intervalId);
setCurrentActiveIndicator(curIndex);
intervalId = setInterval(function () {
if ((step < 0) && (Math.abs(element.offsetLeft + step) < Math.abs(target))) {
element.style.left = element.offsetLeft + step + "px";
} else {
if (Math.abs(target - element.offsetLeft) > Math.abs(step)) {
element.style.left = element.offsetLeft + step + "px";
} else {
clearInterval(intervalId);
intervalId = -1;
element.style.left = target + "px";
if (autoplay) {
startAnimation(element);
}
}
}
}, time);
}
}
/*/ 左右翻页,改变轮播图的left值,改变当前显示的图片,再进行翻页动作,使用户感受不到过明显的跳转变化,
*/
function prev() {
var element = slider_item_container;
var li = element.children;
curIndex = curIndex - 1;
if (curIndex < 0) {
element.style.left = -((li.length-1)*slider_item_width) + "px";
curIndex = li.length-2;
}
animate(element, -(curIndex*slider_item_width));
}
// 点击小圆点,也就是单词调用next(),但需要将要跳转的下标值传入
function next(nextIndex) {
var element = slider_item_container;
var li = element.children;
if ((nextIndex != null) && (typeof(nextIndex) != "undefined")) {
curIndex = nextIndex;
} else {
curIndex = curIndex + 1;
if (curIndex > (li.length-1)) {
element.style.left = 0 + "px";
curIndex = 1;
}
}
animate(element, -(curIndex*slider_item_width));
}
// 自动播放,每次轮播图移动到目标位置后,持续调用startAnimation(),内部也是调用next()
function startAnimation(element) {
if (autoplayId) {
clearTimeout(autoplayId);
}
autoplayId = setTimeout(function () {
next();
}, autoplay_Delay);
}
function setCurrentActiveIndicator(index) {
var indicators = indicator_container.children;
if (index == indicators.length) {
index = 0;
}
for (var i = 0; i < indicators.length; i++) {
if (i == index) {
indicators[i].className = "indicator active";
} else {
indicators[i].className = "indicator";
}
// 判断当前是第几张图并对小圆点加颜色
}
}
总结以上一些小细节
- span设置宽高无效,但设置
position: absolute;
或display: inline-block;
就有效了- 子元素设置了
float: left
,父元素的text-align
就失效了- 圆形
border-radius: 50%;
- 文字上下居中:
line-height
设置和height
一样的值- 水平文字居中
text-align: center;