这是根据网上的教程写的,教程讲的调理很清晰,所以我想把它一步步写下来,算作是一篇笔记吧。脑子笨就要多看多写。
html结构和css样式
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>焦点轮播图</title>
<style type="text/css">
*{ margin: 0; padding: 0; text-decoration: none;}
body { padding: 20px;}
#container { width: 600px; height: 400px; border: 3px solid #333; overflow: hidden; position: relative;}
#list { width: 4200px; height: 400px; position: absolute; z-index: 1;}
#list img { float: left;}
#list div{ width: 600px;height: 400px;float: left;}
#buttons { position: absolute; height: 10px; width: 100px; z-index: 2; bottom: 20px; left: 250px;}
#buttons span { cursor: pointer; float: left; border: 1px solid #fff; width: 10px; height: 10px; border-radius: 50%; background: #333; margin-right: 5px;}
#buttons .on { background: orangered;}
.arrow { cursor: pointer; display: none; line-height: 39px; text-align: center; font-size: 36px; font-weight: bold; width: 40px; height: 40px; position: absolute; z-index: 2; top: 180px; background-color: RGBA(0,0,0,.3); color: #fff;}
.arrow:hover { background-color: RGBA(0,0,0,.7);}
#container:hover .arrow { display: block;}
#prev { left: 20px;}
#next { right: 20px;}
</style>
</head>
<body>
<div id="container">
<div id="list" style="left: -600px;">
<!--<img src="img/5.jpg" alt="1"/>-->
<!--<img src="img/1.jpg" alt="1"/>-->
<!--<img src="img/2.jpg" alt="2"/>-->
<!--<img src="img/3.jpg" alt="3"/>-->
<!--<img src="img/4.jpg" alt="4"/>-->
<!--<img src="img/5.jpg" alt="5"/>-->
<!--<img src="img/1.jpg" alt="5"/>-->
<div style="background-color: #e4b9b9">1</div>
<div style="background-color: #e4b9b9">1</div>
<div style="background-color: #e460b6">2</div>
<div style="background-color: #e4e13f">3</div>
<div style="background-color: #4689e4">4</div>
<div style="background-color: #47e4ad">5</div>
<div style="background-color: #47e4ad">5</div>
</div>
<div id="buttons">
<span index="1" class="on"></span>
<span index="2"></span>
<span index="3"></span>
<span index="4"></span>
<span index="5"></span>
</div>
<a href="javascript:;" id="prev" class="arrow"><</a>
<a href="javascript:;" id="next" class="arrow">></a>
</div>
</body>
</html>
实现原理
功能:点击左右箭头左右滑动显示不同图片,点击小按钮显示对应图片,鼠标移出图片范围实现自动播放。
技能点:DOM操作,定时器,函数递归,事件运用,JS动画,无限滚动
要实现一个完整功能的焦点轮播图效果,我们可以按照这几个步骤来进行:
- 箭头切换
- 无限滚动
- 按钮切换
- 函数动画
- 自动播放
1. 箭头切换
点击左右箭头,图片相应方向切换显示。
代码片段1:
window.οnlοad=function(){
var container=document.getElementById("container");
var list=document.getElementById("list");
var buttons=document.getElementById("buttons").getElementsByTagName("span");
var prev=document.getElementById("prev");
var next=document.getElementById("next");
next.οnclick=function(){
list.style.left = parseInt(list.style.left) - 600 + "px";
}
prev.οnclick=function(){
list.style.left = parseInt(list.style.left) + 600 + "px";
}
}
图片容器list的left起始值是-600px,而每张图片的宽度也是600px,所以当我们点击next箭头时希望下一张图片显示就要给list.style.left减去600px;反方向的话就是加上600px;
这里我们发现
listy.style.left = parseInt(list.style.left) + 600
这个值其实我们可以放在一个函数里面来调用,减少代码量,称为封装。代码片段1可以重写为这样:
window.οnlοad=function(){
var container=document.getElementById("container");
var list=document.getElementById("list");
var buttons=document.getElementById("buttons").getElementsByTagName("span");
var prev=document.getElementById("prev");
var next=document.getElementById("next");
function animate(offset){
list.style.left = parseInt(list.style.left) + offset + "px";
}
next.οnclick=function(){
animate(-600);
}
prev.οnclick=function(){
animate(600);
}
}
这里我们创建了animate函数,给它一个offset参数,点击向前向后调用animate函数,实现图片的切换。
到此为止箭头切换这一步就实现了,但是我们发现,当点击切换到最后一张图片再点击时,图片变成了空白,而我们需要切换到最后一张图片再点击时显示的是第一张图片,要实现这种功能,我们就需要进行 无限滚动操作。
2. 无限滚动
这里只要弄清楚无限滚动的原理其实很简单,我们这个DEMO中为第一张和最后一张添加了与之相同的附属图。当list的偏移值小于-600,也就是当前图片为第一张图片再向前切换的时候,要实现无限滚动,只需要把最后一张图显示出来就好了,也就是说让list的偏移值为-3000就行了。所以,要实现无限滚动,animate方法需要这样改写:
function animate(offset){
var newLeft = parseInt(list.style.left) + offset;
list.style.left = newLeft + "px";
if(newLeft > -600){
list.style.left = -3000 + "px";
}
if(newLeft < -3000){
list.style.left = -600 + "px";
}
}
这时候左右切换基本就实现了,但我们发现左右切换的时候,这些小圆点按钮应该也随之对应切换,这里我们就需要添加新的方法showButton()
var index=1;//用来存放当前显示的图片小圆点
function showButton(){ //给对应的小圆点添加class,而其他的小圆点去掉样式
for(var i=0;i<buttons.length;i++){
if(buttons[i].className=="on"){
buttons[i].className = "";
break;
}
}
buttons[index-1].className="on";
}
在点击切换方法中这样调用
next.οnclick=function(){
if(index==5){ //当到第5张即最后一张图片时将index重置为1,即返回第一张图片
index =1;
}else{
index += 1;
}
showButton();
animate(-600);
}
prev.οnclick=function(){
if(index==1){
index =5;
}else{
index -= 1;
}
showButton();
animate(600);
}
这样我们就是实现了无限滚动,并且小圆点也随之对应变化。而我们还希望当点击任意小圆点的时候也应该显示对应图片,这里我们就需要添加一个按钮切换方法。
3. 按钮切换
点击任意小圆点的时候也应该显示对应图片。
我们就需要判断点击的小圆点与图片的对应索引应该相同。这里我们需要注意,正常按顺序一张张切换的时候,每点击一次list的偏移量就加上或者减去600px;不按顺序的时候,list的偏移量就应该是: -600*(目标index值-当前index值)。
for (var i = 0; i < buttons.length; i++) {
buttons[i].onclick = function () {
var myIndex=parseInt(this.getAttribute("index"));
var offset= -600 * (myIndex-index);
animate(offset);
index=myIndex;
showButton();
}
}
这样按钮切换就基本完成,但是还有一点小BUG,点击当前小圆点的时候,图片又会刷新一遍,于是我们要做一些小改动:
for (var i = 0; i < buttons.length; i++) {
buttons[i].onclick = function () {
if(this.className=="on"){
return;
}
var myIndex=parseInt(this.getAttribute("index"));
var offset= -600 * (myIndex-index);
animate(offset);
index=myIndex;
showButton();
}
}
到这里按钮点击切换就完成了。
4. 函数动画
我们不希望切换的时候是整张图片而是慢慢的平滑的切换,这里就需要将动画函数进行改动:
function animate(offset) {
var newLeft = parseInt(list.style.left) + offset;
var time=300;//位移总时间
var interval=10;//位移间隔时间
var speed=offset/(time/interval); //每次位移量
function go(){
if((speed<0 && parseInt(list.style.left)>newLeft) ||(speed>0 && parseInt(list.style.left)<newLeft)){
list.style.left = speed + parseInt(list.style.left) + "px";
setTimeout(go,interval);//
}
else{
list.style.left = newLeft + "px";
if (newLeft > -600) {
list.style.left = -3000 + "px";
}
if (newLeft < -3000) {
list.style.left = -600 + "px";
}
}
}
go();
}
这里用到了递归函数的知识点,简单将就是在函数体内调用本函数。
当我们不停点击切换的时候,图片不停地切换,这样会造成卡顿的现象,我们需要进行改动,当一张图片完全显示以后才能再次点击切换,当每次动画结束时点击切换才会调用animate()方法。添加一个变量 animated初始值为flase;然后进行判断。
var animated=false;
function animate(offset) {
animated=true;
var newLeft = parseInt(list.style.left) + offset;
var time=300;//位移总时间
var interval=10;//位移间隔时间
var speed=offset/(time/interval); //每次位移量
function go(){
if((speed<0 && parseInt(list.style.left)>newLeft) ||(speed>0 && parseInt(list.style.left)<newLeft)){
list.style.left = speed + parseInt(list.style.left) + "px";
setTimeout(go,interval);//
}
else{
animated=false;
list.style.left = newLeft + "px";
if (newLeft > -600) {
list.style.left = -3000 + "px";
}
if (newLeft < -3000) {
list.style.left = -600 + "px";
}
}
}
go();
}
next.onclick = function () {
if (animated) {
return;
}
if (index == 5) { //当到第5张即最后一张图片时将index重置为1,即返回第一张图片
index = 1;
} else {
index += 1;
}
showButton();
animate(-600);
}
prev.onclick = function () {
if (animated) {
return;
}
if (index == 1) {
index = 5;
} else {
index -= 1;
}
showButton();
animate(600);
}
for (var i = 0; i < buttons.length; i++) {
buttons[i].onclick = function () {
if (animated) {
return;
}
if(this.className=="on"){
return;
}
var myIndex=parseInt(this.getAttribute("index"));
var offset= -600 * (myIndex-index);
animate(offset);
index=myIndex;
showButton();
}
}
5. 自动播放
通常我们希望某些时候图片可以自动切换,我们就需要添加新的方法。
每隔固定时间自动点击切换按钮,这就是自动播放的原理。就需要用到定时器setInterval();
var interval=3000;
var timer;
function play(){
timer=setInterval(function(){next.onclick();},interval);
}
function stop(){
clearInterval(timer);//清除定时器
}
container.οnmοuseοver=stop;
container.οnmοuseοut=play;
play();
这里我们发现了新的定时器setInterval,这和之前的setTimeout有什么区别呢?
setInterval在执行完一次代码之后,经过了那个固定的时间间隔,它还会自动重复执行代码
setTimeout只执行一次那段代码。
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
完整焦点轮播图代码JS
window.οnlοad=function() {
var container = document.getElementById("container");
var list = document.getElementById("list");
var buttons = document.getElementById("buttons").getElementsByTagName("span");
var prev = document.getElementById("prev");
var next = document.getElementById("next");
var index = 1;//用来存放当前显示的图片小圆点
var animated=false;
var interval=3000;
var timer;
function showButton() { //给对应的小圆点添加class,而其他的小圆点去掉样式
for (var i = 0; i < buttons.length; i++) {
if (buttons[i].className == "on") {
buttons[i].className = "";
break;
}
}
buttons[index - 1].className = "on";
}
function animate(offset) {
animated=true;
var newLeft = parseInt(list.style.left) + offset;
var time=300;//位移总时间
var interval=10;//位移间隔时间
var speed=offset/(time/interval); //每次位移量
function go(){
if((speed<0 && parseInt(list.style.left)>newLeft) ||(speed>0 && parseInt(list.style.left)<newLeft)){
list.style.left = speed + parseInt(list.style.left) + "px";
setTimeout(go,interval);//
}
else{
animated=false;
list.style.left = newLeft + "px";
if (newLeft > -600) {
list.style.left = -3000 + "px";
}
if (newLeft < -3000) {
list.style.left = -600 + "px";
}
}
}
go();
}
function play(){
timer=setInterval(function(){next.onclick();},interval);
}
function stop(){
clearInterval(timer);//清除定时器
}
next.onclick = function () {
if (animated) {
return;
}
if (index == 5) { //当到第5张即最后一张图片时将index重置为1,即返回第一张图片
index = 1;
} else {
index += 1;
}
showButton();
animate(-600);
}
prev.onclick = function () {
if (animated) {
return;
}
if (index == 1) {
index = 5;
} else {
index -= 1;
}
showButton();
animate(600);
}
for (var i = 0; i < buttons.length; i++) {
buttons[i].onclick = function () {
if (animated) {
return;
}
if(this.className=="on"){
return;
}
var myIndex=parseInt(this.getAttribute("index"));
var offset= -600 * (myIndex-index);
animate(offset);
index=myIndex;
showButton();
}
}
container.οnmοuseοver=stop;
container.οnmοuseοut=play;
play();
}
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
到此为止,我们的这个焦点轮播图就算大功告成了。但是这中方法还是有一定的问题,我们必须为第一张和最后一张图添加对应的附属图,拓展性不是特别强。
第一次写,错误肯定会有,先草草结束吧。