这次撸了一把轮播图的代码,为了捋一遍思路,也是跟小伙伴们分享,所以把它记录在我的个博上给大家参考咯!有错请指教,勿喷蟹蟹啦!
实现的轮播图最终效果如下(一直看这个gif我好晕啊…):
实现效果:将鼠标移到对应的数字会无缝切换到相应的图片上去,我是通过left属性实现的。
- 首先,编写
html
结构,如下:
<div id="box">
<div class="inner">
<ul>
<li><img src="images/test1.jpg" alt=""/></li>
<li><img src="images/test2.jpg" alt=""/></li>
<li><img src="images/test3.jpg" alt=""/></li>
<li><img src="images/test4.jpg" alt=""/></li>
<li><img src="images/test5.jpg" alt=""/></li>
<li><img src="images/test6.jpg" alt=""/></li>
</ul>
<div class="square">
<span class="current">1</span>
<span>2</span>
<span>3</span>
<span>4</span>
<span>5</span>
<span>6</span>
</div>
</div>
- 而后,编写
css
:
<style>
*{
margin: 0;
padding: 0;
}
ul{
list-style: none;
}
img{
vertical-align: top;
}
.box{
width: 500px;
height: 312px;
margin: 100px auto;
padding: 5px;
border: 1px solid pink;
}
.inner {
width: 500px;
height: 312px;
background-color: pink;
overflow: hidden;
position: relative;
}
.inner ul {
/* 如果没有设定width为1000%的话,IMG设定左浮动会失效,因为宽度已经被限制 */
width: 1000%;
position: absolute;
top: 0;
left: 0;
}
.inner li{
float: left;
}
/* 下面是导航 */
.square{
position: absolute;
bottom: 10px;
right: 10px;
}
.square span{
display: inline-block;
width: 16px;
height: 16px;
background-color: #ffffff;
line-height: 16px;
text-align: center;
cursor: pointer;
}
.square span.current{
background-color: orangered;
color: #ffffff;
}
</style>
在写css的时候要注意几点(踩过的坑啊。。。):
- 为了使图片无缝衔接,要设定每个列表项
float:left
,变成这样:
只有这样,我们才能通过改变left
来对图片进行移动。 - 要把
ul
标签的宽度设成width:1000%
,否则float-left
会失效,变成这样:
这是因为我们已经把宽度固定成导入的img
的宽度了,再设定浮动后一个img
并不会浮动到前一个img
的右边,因为那已经超过了我们设置的宽度。 - 设置的
class="current"
是用来标记当前触发的span
。
- 重头戏来了,接下来我们使用
Javascript
来编写轮播图实现的业务逻辑。
我们要做两件事: 一是实现span的鼠标移入事件业务处理逻辑。 二是根据移入的span转到对应的图片。
接下来我们先来实现span
的鼠标移入事件业务处理逻辑。(要看完整JS代码请直接移至篇末。)
首先,当然是先获取对应的dom节点
:
var box = document.getElementById("box");
var inner = box.children[0];
var ulObj = inner.children[0];
var spanObjs = inner.children[1].children;
var imgWidth = inner.offsetWidth;
要处理span
,我们当然是要获取所有span
这个元素节点了。
=>至于这里的ulObj
和imgWidth
是第二步要使用的,请看后头。
获取完所有的span
标签后,我们要循环遍历span
标签,做两件事:
- 为它们设定一个index属性进行标记
- 为每一个
span
注册一个鼠标移入事件onmouseover
:先清空所有span
的class
样式;然后为当前鼠标移入的span
添加current
类样式;最后我们调用animate
(自己定义的方法)根据当前鼠标移入的span
转到对应的图片。
for(var i=0;i<spanObjs.length;i++){
spanObjs[i].setAttribute("index",i);
spanObjs[i].onmouseover = function(){
for(var j=0;j<spanObjs.length;j++){
// 所有span的进入都清空
spanObjs[j].removeAttribute("class");
}
this.className = "current";
var index = this.getAttribute("index");
animate(ulObj,-imgWidth*index);
};
}
接下来,我们开始处理图片的轮播,它的原理是这样子的:
开头的时候我们就提过,我们是使用left
属性来实现轮播效果的,什么意思呢?
当我们用
float:left
将每一个列表项都设定为浮动后,所有图片排成一排。这个时候我们可以设ul
标签的left
属性值,该值为负,整个ul
向左移,为正向右移。通过将ul
标签向左或向右移一个或n个图片宽度来显示左或右的图片。
因此,上一步获得的ulObj
和imgWidth
就是用来做这个事情的。我们定义animate
方法,该方法传入两个参数,element
参数用来指定要移动的元素,target
用来指定要移动的距离。
为了实现轮播图的动画效果,我们使用setInterval
定时器来实现,变量step
用来指定每次移动的距离,代码如下:
function animate(element,target){
clearInterval(element.timeId);
element.timeId = setInterval(function(){
var step = 10;
var current = element.offsetLeft;
step = current<target?step:-step;
current+=step;
if(Math.abs(current-target)>Math.abs(step)){
element.style.left = current+"px";
} else{
clearInterval(element.timeId);
element.style.left = target+"px";
}
},30);
}
这里解释一下:
-
current
变量获得当前的left
值,通过与目标位置进行对比来判断要向左移(step
为负)还是向右移(step
为正)。 - 通过将当前位置
current
与目标位置target
的距离和每一次的步长step
进行对比,来判断是继续移动,还是直接到达目标位置,并终止定时器(clearInterval
)。 - 在定时器开始之前,记得先清除该元素下所有的定时器,避免混乱。
好啦,这里附上源代码(JS):
<script>
var box = document.getElementById("box");
var inner = box.children[0];
var ulObj = inner.children[0];
var spanObjs = inner.children[1].children;
var imgWidth = inner.offsetWidth;
for(var i=0;i<spanObjs.length;i++){
spanObjs[i].setAttribute("index",i);
spanObjs[i].onmouseover = function(){
for(var j=0;j<spanObjs.length;j++){
// 所有span的进入都清空
spanObjs[j].removeAttribute("class");
}
this.className = "current";
var index = this.getAttribute("index");
animate(ulObj,-imgWidth*index);
};
}
function animate(element,target){
clearInterval(element.timeId);
element.timeId = setInterval(function(){
var step = 10;
var current = element.offsetLeft;
step = current<target?step:-step;
current+=step;
if(Math.abs(current-target)>Math.abs(step)){
element.style.left = current+"px";
} else{
clearInterval(element.timeId);
element.style.left = target+"px";
}
},30);
}
</script>
整理了一下轮播图的实现,就是这样的。不过做完也在思考一个问题,这个案例中有一个限制就是要求所有的源图片大小都要完全一致,否则效果会很奇怪,有没有其他方法实现轮播图呢?我再继续康康!
谢谢看到这里的伙伴啦,晚安~