最终效果图

效果说明:
- 运行后六张图片自动轮播,同时下方对应的小矩形背景色变蓝。
- 当鼠标停放在图片上时,图片轮播动画暂停,始终显示当前图片;当鼠标移开,图片继续实现轮播动画。
- 当点击左边箭头时,图片右移,显示出上一张图片,同时下方对应的小矩形背景色变蓝;当点击右边箭头时,图片左移,显示下一张图片,同时下方对应的小矩形背景色变蓝。
- 点击下方小矩形时,仅被点击的小矩形变为蓝色,并显示对应的图片。
解析

结构层次解析:
- 最外层是一个大的div,类名为slide。
- slide里面包含了上下两个div:上面div类名为slide_scroll;下面div类名为slide_ctrl。
- slide_scroll里面是一个类名为slide_main的div,该div宽度为两个图片宽度的总和。
- slide_main里面包含了六个类名为slide_pic的div,用来存放img。
- slide_ctrl里面是八个span标签,其中两个是左右箭头,剩下六个是下方的小矩形(小矩形span为js中动态创建,根据图片的张数来生成相同个数的span标签)。
运动思想:
初始状态为:左边一张图片,右边紧挨着叠放了五张图片。
- 当点击左边箭头时,当前图片右移,上一张图片马上定位至当前可视位置的左边,然后立即缓动动画移入当前可视位置,同时对应的矩形变为蓝色。
- 当点击右边箭头时,当前图片左移,下一张图片马上定位至当前可视位置的右边,然后立即缓动动画移入当前可视位置,同时对应的矩形变为蓝色。
- 当点击小矩形时,被点击的矩形变蓝
- 被电击的小矩形的index值大于当前显示图片的角标值时,当前图片左移,将index值赋值为下一个当前图片,首先将该图片定位至可视位置的右边,再立即缓动动画移至当前可视位置
- 被电击的小矩形的index值小于当前显示图片的角标值时,当前图片右移,将index值赋值为下一个当前图片,首先将该图片定位至可视位置的左边,再立即缓动动画移至当前可视位置
代码以及注释
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>轮播图</title>
<style>
*{
margin: 0;
padding: 0;
border: none;
}
.slide{
width: 310px;
height: 260px;
margin: 100px auto;
position: relative;
overflow: hidden;
}
.slide .slide_scroll{
width: 310px;
height: 220px;
position: relative;
}
.slide .slide_scroll .slide_main{
width: 620px;
height: 220px;
}
.slide .slide_scroll .slide_main .slide_pic{
width: 310px;
height: 220px;
position: absolute;
left: 0;
top: 0;
}
.slide .slide_ctrl{
width: 310px;
height: 40px;
text-align: center;
}
.slide .slide_ctrl .slide_left,.slide .slide_ctrl .slide_right{
width: 20px;
height: 34px;
position: absolute;
top: 50%;
margin-top: -34px;
background: url("images/icon.png") no-repeat;
}
.slide .slide_ctrl .slide_left{
left: 0;
background-position: 0 0;
}
.slide .slide_ctrl .slide_right{
right: 0;
background-position: -9px -45px;
}
.slide_item{
width: 20px;
height: 5px;
background: url("images/icon.png") -24px -790px;
display: inline-block;
margin: 5px;
text-indent:20em;
}
.curr{
background-position:0 -770px;
}
</style>
</head>
<body>
<div class="slide">
<div class="slide_scroll">
<div class="slide_main">
<div class="slide_pic">
<a href="#">

</a>
</div>
<div class="slide_pic">
<a href="#">

</a>
</div>
<div class="slide_pic">
<a href="#">

</a>
</div>
<div class="slide_pic">
<a href="#">

</a>
</div>
<div class="slide_pic">
<a href="#">

</a>
</div>
<div class="slide_pic">
<a href="#">

</a>
</div>
</div>
</div>
<div class="slide_ctrl">
<span class="slide_left"></span>
<!--<span class="slide_item"></span>
<span class="slide_item"></span>
<span class="slide_item"></span>
<span class="slide_item"></span>
<span class="slide_item"></span>
<span class="slide_item"></span>-->
<span class="slide_right"></span>
</div>
</div>
<script>
window.onload = function () {
var slide = document.getElementsByTagName('div')[0];
var slide_scroll = slide.children[0];
var slide_main = slide_scroll.children[0];
var slide_pic = slide_main.children;
var slide_ctrl = slide.children[1];
var slide_spans = slide_ctrl.children;
var pic_w = slide_pic[0].offsetWidth;
//根据图片的个数添加图片下方的小矩形
for(var i=0; i<slide_pic.length; i++) {
var slide_item = document.createElement('span');
slide_item.className = 'slide_item';
/*一直向slide_ctrl的第一个子标签前插入
*(新插入的节点总会成为第一个子标签),
*相当于倒序插入,所以innerHTML值为slide_pic.length - i - 1
*(0,1,2,3,4,5) */
slide_item.innerHTML = slide_pic.length - i - 1;
slide_ctrl.insertBefore(slide_item,slide_ctrl.children[1]);
}
//给第一个小矩形设置背景色
slide_ctrl.children[1].className = 'slide_item curr';
/* 给图片定位,第一张图片在左边,
* 剩余的所有图片都绝对定位叠在右边*/
for(var i=1; i<slide_pic.length; i++) {
slide_pic[i].style.left = pic_w + 'px';
}
//点击事件
var iNow = 0;
for(var i=0; i<slide_spans.length; i++) {
var mySpan = slide_spans[i];
mySpan.onclick = function () {
if(this.className == 'slide_left') {//点击左边箭头
buffer(slide_pic[iNow],{left:pic_w}); //先将当前图片右移
iNow --; //找到上一张图片的角标值设为当前
if(iNow < 0){
iNow = slide_pic.length - 1;
}
slide_pic[iNow].style.left = -pic_w + 'px';//上一张图片移到左边
buffer(slide_pic[iNow],{left:0});//动画将上一张图片移到当前位置
} else if(this.className == 'slide_right'){//点击右边箭头
buffer(slide_pic[iNow],{left:-pic_w});
iNow ++;
if(iNow > slide_pic.length-1){
iNow = 0;
}
slide_pic[iNow].style.left = pic_w + 'px';
buffer(slide_pic[iNow],{left:0});
} else {//点击下面一排小矩形
//注意点:this.innerHTML是字符串类型,所以必须将其强制转换为数值类型,避免后面用到iNow出现错误。
var index = parseInt(this.innerHTML);
if(index > iNow){
buffer(slide_pic[iNow],{left:-pic_w});
iNow = index;//及时更新iNow值
slide_pic[iNow].style.left = pic_w + 'px';
buffer(slide_pic[iNow],{left:0});
}else if(index < iNow) {
buffer(slide_pic[iNow],{left:pic_w});
iNow = index;
slide_pic[iNow].style.left = -pic_w + 'px';
buffer(slide_pic[iNow],{left:0});
}
}
changeIndex();
}
}
//运行后自动轮播
var timer = setInterval(autoPlay,1000);
slide.onmouseover = function () {
clearInterval(timer);
};
slide.onmouseout = function () {
timer = setInterval(autoPlay,1000);
};
//改变下方小矩形对应图片显示背景色
function changeIndex(){
for(var i=1; i<slide_spans.length-1; i++){
slide_spans[i].className = 'slide_item';
}
slide_spans[iNow+1].className = 'slide_item curr';
}
//自动轮播的函数
function autoPlay(){
buffer(slide_pic[iNow],{left:-pic_w});
iNow ++;
if(iNow > slide_pic.length-1){
iNow = 0;
}
slide_pic[iNow].style.left = pic_w + 'px';
buffer(slide_pic[iNow],{left:0});
changeIndex();
}
function buffer(obj,json,fn) {
clearInterval(obj.timer);
//初始值、速度、目标值
var begin = 0;
var speed = 0;
var target = 0;
obj.timer = setInterval(function () {
var flag = true;
for(var key in json) {
//当需求为更改透明度时需另外判断
if('opacity' == key) {
begin = parseInt(parseFloat(getAtributeValue(obj,key)) * 100);
target = parseInt(json[key] * 100);
} else if('scrollTop' == key){
begin = obj.scrollTop;
target = parseInt(json[key]);
}else {
begin = parseInt(getAtributeValue(obj,key));
target = parseInt(json[key]);
}
//速度为正值时需向上取值,速度为负值时需向下取值
speed = target > begin ? Math.ceil((target - begin) * 0.2) : Math.floor((target - begin) * 0.2);
if('opacity' == key) {
obj.style.opacity = parseFloat((begin + speed) / 100);
obj.style.filiter = 'alpha(opactiy:' + (begin + speed) + ')';
} else if('scrollTop' == key) {
obj.scrollTop = begin + speed;
} else if('zIndex' == key){
obj.style.zIndex = json[key];
}else {
obj.style[key] = begin + speed + 'px';
}
//为了避免当其中一个属性到达目标值的情况发生,需声明一个布尔值变量记录,只要有一个属性未能
//到达目标值,该布尔值就为false,当且仅当为true时,清除定时器。
if(begin != target) {
flag = false;
}
}
if(flag) {
clearInterval(obj.timer);
if(fn){
fn();
}
}
},30);
}
}
</script>
</body>
</html>
注意点:
- slide_main类的div负责滚动,不负责定位,因此slide_pic定位在slide_scroll上;slide_left和slide_right(即两个箭头)定位在总的大盒子上。
- 小矩形的个数由图片张数决定,所以在js中动态创建并添加。
- 及时更新iNow值,该值表示当前显示图片的角标值。
- buffer函数为一个简单的缓动运动框架。
网友评论