在JS写轮播图的学习过程当中,不可避免地碰到了许多疑问和值得划下重点的地方,以下如有理解错误的地方,也请多多指教。
当我把JS写在head里头,在没有使用任何方法延迟加载JS代码的情况下,发现getElementsByTagName和getElementsByClassName仍然可以获取到Dom数组对象,而getElementById却无法获取到对象,返回的是null值。有人说是因为阻塞效应,然而为何阻塞效应没有影响到getElementsByTagName和getElementsByClassName的渲染呢?还有人说是因为动态获取和静态获取的缘故,可是我暂且还没找到这两种获取方式对页面渲染顺序造成影响的说法。所以该疑问目前尚未得到解决。
a标签的href的值为空时,点击之后会返回页面顶端,所以需要用到href:"javascript:void(0)",该写法让a标签在默认情况下被点击之后不进行任何操作,页面也不会跳转。
当绑定鼠标经过和离开的事件时,对象应该是一个包含图片div,圆点span和前后页a标签的大容器div,而不是仅仅是图片div。如果对象只是图片的div,那么当鼠标停留在圆点span和前后页a标签上时,图片仍会继续切换,选择图片就变得不可控制。
我个人总结的思路是:整个图片切换是需要依靠index来传递对象索引的。先封装换图函数(代码里的changePic()),再通过不同的操作和事件给该函数传递不同的index值,由index索引决定需要做样式更改的对象。具体思路见代码注释。
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" href="PicPlayer.css">
<script src="PicPlayer.js" defer="defer"></script>
</head>
<body>
<div id="container">
<div id="banner">
<a href="">
<div class="picSlide onShowed">
<img src="img/bg1.jpg">
</div>
</a>
<a href="">
<div class="picSlide">
<img src="img/bg2.jpg">
</div>
</a>
<a href="">
<div class="picSlide">
<img src="img/bg3.jpg">
</div>
</a>
</div>
<a href="javascript:void(0)" class="button" id="preSlide">
</a>
<a href="javascript:void(0)" class="button" id="nextSlide">
</a>
<div class="choice">
<span class="pointSelected"></span>
<span></span>
<span></span>
</div>
</div>
</body>
</html>
CSS:
*{margin: 0;padding: 0;}
#container{width: 1200px;height: 460px;margin:50px auto;position: relative;}
#banner{width: 1200px;height: 460px;position: relative;}
.picSlide{width: 1200px;height: 460px;position: absolute;display: none;}
.onShowed{display: block;}
.button{position: absolute;width: 40px;height: 80px;left: 244px;top: 50%;margin-top: -40px;
background: url(arrow.png) no-repeat center;}
.button:hover{background-color: grey;opacity: 0.5;}
#preSlide{transform: rotate(180deg);}
#nextSlide{right: 0;left: auto;}
.choice{position: absolute;right: 50px;bottom: 30px;}
.choice span{width: 13px;height: 13px;display:inline-block;margin-left:10px;cursor:pointer;
border-radius: 50%;background:rgba(7,17,27,0.5);box-shadow: 0 0 0 2px rgba(255,255,255,0.8) inset;}
/*注意选择器的权重和优先级。权重:10+1=11*/
.choice span.pointSelected{box-shadow: 0 0 0 2px rgba(7,17,27,0.5) inset;background: white;}
/*注意选择器的权重和优先级。权重:10+1+10=21*/
JS:
var getContainer=document.getElementById("container");
var picSlides=document.getElementsByClassName("picSlide");
var points=document.getElementsByTagName("span");
var previous=document.getElementById("preSlide");
var next=document.getElementById("nextSlide");
var index=0;
var timer;
// 第三步,定义鼠标经过和鼠标离开所触发的函数:
// 1.鼠标经过,取消定时函数
// 2.鼠标离开,触发定时函数
// 3.由于一进页面图片就需要进行切换,因此函数最后添加onmouseout()自动触发鼠标离开事件,即自动执行定时函数。也可以直接添加定时函数startSlide()
function moveOn(){
getContainer.onmouseover=function(){
clearInterval(timer);
}
getContainer.onmouseout=function(){
startSlide();
}
getContainer.onmouseout(); //或者直接执行startSlide()
// 第四步,点击圆点进行相应图片切换:
for(var j=0;j<points.length;j++){ //遍历span标签
points[j].index=j; //给每个span定义下标以方便获取使用
points[j].onclick=function(){ //定义某个span的点击事件
index=this.index; //赋值给变量index,即被点击的span的下标
changePic(); //获得新的index值,传给换图函数changePic(),切换相应的图片,并作出相应样式设置
}
}
// 第五步,定义前一页函数和后一页函数:
previous.onclick=function(){ //绑定前一张点击事件
index--; //前一张index即当前对象的index减去1
if(index<0){ //但是下标不能为负值,最小为0
index=picSlides.length-1; //index小于0的话,则回到最后一张图片,以此循环
}
changePic(); //传递index的值给换图函数changePic(),切换相应的图片,并作出相应的样式设置
}
next.onclick=function(){ //绑定后一张点击事件
index++; //后一张index即当前对象的index加1
if(index>=picSlides.length){ //但是下标不能大于等于picSlides的数组长度
index=0; //否则回到首张图片的下标,以此循环
}
changePic(); //传递index的值给换图函数changePic(),切换相应的图片,并作出相应的样式设置
}
}
// 第二步,定义定时函数:
// 1.让index递增,以便传递新下标给换图函数(这样换图函数才能对下一张图片进行显示操作)
// 2.限制index的递增范围,必须要在图片数(类名为picSlide的div数量)范围之内,如果超过范围,回到index=0重新递增,即重新从第一张图片开始进行显示设置
// 3.执行换图函数,定时3秒执行一次,每次都会传递一个新的index值给换图函数
function startSlide(){
timer=setInterval(function(){
index++;
if(index>=picSlides.length){
index=0;
}
changePic();
}
,2000)
}
// 第一步,定义换图函数:
// 1.遍历所有图片容器div和用作选项圆点的span标签,分别对其进行隐藏和样式还原
// 2.对下标同为index值的div和span分别进行显示操作和样式设置
function changePic(){
for(var i=0;i<picSlides.length;i++){
picSlides[i].style.display="none";
points[i].className=" ";
}
picSlides[index].style.display="block";
points[index].className="pointSelected";
}
moveOn(); //由于一进页面,鼠标经过离开,点击圆点和前后翻页事件都需要具备触发条件,所以其封装函数moveOn需要被执行