具体代码和思路如下:
效果图:
思路:
常见轮播图的功能就是:
①图片自动轮换
②点击左右两侧的箭头切换
③正下方的小点显示正在播放第几张
实现思路:
①设置一个container容器用来显示图片。container大小为图片大小。将该container居中显示,且position设置为relative。这样可以使它的子元素相对于它进行绝对定位
②设置一个容器box用来装图片。设置float:left使所有图片在该div中平铺。因此这个容器的宽度应该为所有图片宽度的总和,高度为图片高度。该容器position设置为absolute。
③设置图片个数个span,设置span的宽高相同,为span设置白色背景。此时span显示为白色正方形。设置boder-radius为50%。此时span为白色原点。然后左右的箭头就用尖括号就可以。将圆点和箭头用绝对定位放在和合适位置即可。
原理:利用js动态改变box的left,让他在container显示。可以想象成你用几幅图构成很图你站着不动,让别人拉这幅画往左移,每次移动一副图的位置,站在你的视角就看到图片的自动切换效果。
④用setInterval设置固定时间间隔改变left值,当鼠标移入container时应当让轮播停止,使用clearInterval清除循环。等到鼠标移出重新开始循环执行使left改变。
需要注意的点:
1、container一定要设置overflow,否则你真的会看到一幅很长的画被拽着往左拉
2、position的absolute定位时相对与最近position为absolute/relative/fixed的祖先元素,找不到时就相对于初始块(initial containing block)定位。所以container必须设置position。
3、js中是无法直接获取css中设置的left值的,所以要用offsetLeft来获取初始left值。两者的区别如下:
- 定义了position:relative或absolute属性的元素才有left属性,元素都有offsetLeft属性。
- 元素内联样式中设置了left,才能通过div.style.left获取;offsetLeft直接通过div.offsetLeft获取。
- left可读可写,获取到的是字符串;offsetLeft只读,获取到的是数字。
因为父元素是存在position的因此这里的offsetLeft就可以取到left值。但是注意offsetLeft是只读属性,所以设置还是应该用left进行位置改变。
4、可以用href="javascript:;"来取消a标签的本身绑定事件。
5、鼠标的移出事件用onmouseleave不要用onmouseout,因为onmouseout会有时间冒泡。
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>轮播图</title>
<style type="text/css">
*{
margin: 0px;
padding: 0px;
text-decoration: none;
}
.container{
position: relative;
overflow: hidden;
width: 300px;
height: 200px;
margin: 100px auto;
box-shadow: 0 0 5px green;
}
#box{
width: 1200px;
position: absolute;
z-index: 1;
height:200px;
}
.pic{
float: left;
}
.pic img{
width: 300px;
height: 200px;
}
.container .arrow {
position: absolute;
top: 35%;
color: white;
padding:0px 14px;
border-radius: 50%;
font-size: 50px;
z-index: 2;
}
.container .arrow_left {
left: 10px;
}
.container .arrow_right {
right: 10px;
}
.container:hover .arrow {
display: block;
}
.container .arrow:hover {
background-color: rgba(0,0,0,0.2);
}
.buttons{
z-index: 2;
position: absolute;
top: 85%;
left: 50%;
margin-left: -40px;
}
.buttons span{
height: 10px;
width: 10px;
display: inline-block;
background: #888888;
border-radius: 50%;
font-size: 36px;
margin-left: 5px;
}
</style>
</head>
<body>
<div class="container">
<div id="box" >
<div class="pic"><img src="./images/1.jpg" /></div>
<div class="pic"><img src="./images/2.jpg" /></div>
<div class="pic"><img src="./images/3.jpg" /></div>
<div class="pic"><img src="./images/4.jpg" /></div>
</div>
<div class="buttons">
<span></span>
<span></span>
<span></span>
<span></span>
</div>
<a href="javascript:;" rel="external nofollow" class="arrow arrow_left"><</a>
<a href="javascript:;" rel="external nofollow" class="arrow arrow_right">></a>
</div>
<script type="text/javascript">
window.onload =function(){
var pic = document.getElementsByClassName('pic');
var container = document.querySelector(".container")
var btn = document.querySelector('.buttons');
var light = btn.getElementsByTagName('span');
var len = pic.length;
var wrap = document.getElementById('box');
var next = document.querySelector(".arrow_right");
var prev = document.querySelector(".arrow_left");
var index = 0;
next.onclick = function () {
next_pic();
}
prev.onclick = function () {
prev_pic();
}
function next_pic () {
//此处要用offsetLeft获取值 在css样式中定义的left无法直接获取。而且offsetLeft为数值,而left为字符串
var Left = parseInt(wrap.offsetLeft);
light[index].style.background = '#888888'
if(Left == -900){
Left = 0;
index = 0;
}else{
Left -= 300;
index++;
}
light[index].style.background = '#ffffff'
console.log(wrap.offsetLeft);
wrap.style.left = Left + "px";
}
function prev_pic () {
var Left = parseInt(wrap.offsetLeft);
if(Left == 0){
Left = -900;
}else{
Left += 300;
}
console.log(wrap.offsetLeft);
wrap.style.left = Left + "px";
}
var pos = 0;
var show = function()
{
var timer = setInterval(function(){
next_pic();
},2000);
return timer;
}
var timer = show();
container.onmouseenter = function () {
clearInterval(timer);
}
container.onmouseleave = function () {
show();
}
}
</script>
</body>
</html>
前两天面试时面试官问我你有没有实现过轮播图,我说用bootstrap实现过。问我有没有读过源码,我说没有。然后面试过后我就说如果能过我一定要自己写一遍。感谢面试官不计较我这个失误。总体来说不难,不过涉及很多小细节。这次由于时间原因做的比较简单,理了个思路。感觉把left改变用animate去实现动画可能效果会更好一点。