无缝轮播图
(使用节点操作)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>
*{
padding:0;
margin:0;
}
body{
background:#F5F5F5;
}
#content{
300px;
height:200px;
background:#fff;
margin:50px auto;
position: relative;
overflow:hidden;
}
#divs{
1200px;
height:100%;
position: absolute;
}
#divs>div{
300px;
height:100%;
float:left;
text-align:center;
line-height:200px;
font-size:30px;
}
#lis{
list-style: none;
position: absolute;
right:10px;
bottom:10px;
}
#lis>li{
30px;
height:30px;
background: #ccc;
border-radius:30px;
float:left;
margin:0 6px;
text-align: center;
line-height: 30px;
}
#btns{
100%;
height:30px;
position: absolute;
top:50%;
left:0;
margin-top:-15px;
}
#btns>div{
30px;
height:50px;
background:rgba(0,0,0,.4);
float:left;
text-align: center;
line-height:50px;
font-size:22px;
font-weight: 300;
}
#btns>div:last-child{
float:right;
}
</style>
</head>
<body>
<div id="content">
<div id="divs">
<div style="background: red">1</div>
<div style="background: green">2</div>
<div style="background: blue">3</div>
<div style="background: yellow">4</div>
</div>
<ul id="lis">
<li style="background:black;color:#ccc">1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<div id="btns">
<div id="prev"><</div>
<div id="last">></div>
</div>
</div>
</body>
<!-- 引入封装好的运动函数 -->
<script src="./run.js"></script>
<script>
//整个轮播图
var content=document.getElementById('content');
//轮播图区域
var box=document.getElementById('divs');
//轮播图各个滑动对象
var divs=document.getElementById('divs').getElementsByTagName('div');
//对应每个滑动对象的按钮
var lis=document.getElementById('lis').getElementsByTagName('li');
//左prev(上一张) 右last(下一张)按钮
var prev=document.getElementById('prev');
var last=document.getElementById('last');
// 按钮下标 上一张==>num-- 下一张==>num++
var num=0;
//开关作用:当滑动对象未滑完不允许点击其他
var istrue=true;
//下一张 滑动==>封装函数
function move(){
//点击 if 成立 后 istrue 取反 ==> 开关作用
if(istrue){
//关闭开关
istrue=false;
//下一张+1,超过总数回0
num++;
if(num==lis.length){
num=0;
}
//当前滑块 对应 相应按钮 使其显色
for(var i=0;i<lis.length;i++){
lis[i].style.background="#ccc";
lis[i].style.color='black';
}
lis[num].style.background="black";
lis[num].style.color='#ccc';
//复制当前即(第一张)添加到所有滑块最后
var newNode=divs[0].cloneNode(true);
box.appendChild(newNode);
//调用运动函数 run(运动对象[轮播图区域],运动目标,回调函数[运动完后...])
run(box,-300,function(isok){
// console.log(`我拿到了定时器结束的时候返回的随机值${isok}`);
// 当到达目标后停止滑动
if(isok){
//打开开关
istrue=true;
//删除第一个子节点
box.removeChild(divs[0]);
//且让轮播图区域的left回原点0
box.style.left=0;
}
});
}
};
//点击下一张
last.onclick=move;
//自动轮播下一张
var timer1=setInterval(move,2000);
//移入整个轮播图时 停止轮播==>清除定时器
content.onmouseover=function(){
clearInterval(timer1);
}
//移出整个轮播图时 开始轮播==>开启定时器
content.onmouseout=function(){
timer1=setInterval(move,2000);
}
//点击上一张
prev.onclick=function(){
if(istrue){
//关闭开关
istrue=false;
//点击上一张-1,当等于-1时,回到最后一张==> divs长度-1
num--;
if(num==-1){
num=divs.length-1;
}
//当前滑块 对应 相应按钮 使其显色
for(var i=0;i<lis.length;i++){
lis[i].style.background="#ccc";
lis[i].style.color='black';
}
lis[num].style.background="black";
lis[num].style.color='#ccc';
//复制最后一张,添加到第一个滑块之前
var newNode=divs[divs.length-1].cloneNode(true);
box.insertBefore(newNode,divs[0]);
//运动前先把box整个轮播图往左边一个滑块大小,给接下来的滑动做好准备
box.style.left='-300px';
//调用运动函数 run(运动对象[轮播图区域],运动目标,回调函数[运动完后...])
run(box,0,function(isok){
if(isok){
//删除最后一个子节点,记得此时比原来多一张
box.removeChild(divs[divs.length-1]);
//打开开关
istrue=true;
}
});
}
}
//对应每个滑动对象的按钮 绑定点击事件
for(var i=0;i<lis.length;i++){
//给每个按钮添加索引
lis[i].index=i;
lis[i].onclick=function(){
//获取 当前点击索引this.index 减去 点击前滑块或按钮的下标num 得到 间隔数量tap
var tap=this.index - num;
//如果间隔数tap大于等于0,说明是往下(右)tap张走
if(tap>=0){
//打开开关
if(istrue){
//关闭开关
istrue=false;
//把 当前点击的索引值this.index 赋给替换 当前的下标num
num=this.index;
//当前滑块 对应 相应按钮 使其显色
for(var i=0;i<lis.length;i++){
lis[i].style.background="#ccc";
lis[i].style.color='black';
}
lis[num].style.background="black";
lis[num].style.color='#ccc';
//复制tap张(从当前即下标0开始)添加到所有滑块最后
for(var i=0;i<tap;i++){
var newNode=divs[i].cloneNode(true);
box.appendChild(newNode);
}
//调用运动函数 run(运动对象[轮播图区域],运动目标,回调函数[运动完后...])
//运动目标 = 每个滑块宽度 * tap间隔数
run(box,-300*tap,function(isok){
// console.log(`我拿到了定时器结束的时候返回的随机值${isok}`);
// 当到达目标后停止滑动
if(isok){
//打开开关
istrue=true;
//删除tap次第一个子节点
//(删除完一个,下一个下标也变成0,所以依然删除下标0的节点)
for(var j=0;j<tap;j++){
box.removeChild(divs[0]);
}
//且让轮播图区域的left回原点0
box.style.left=0;
}
});
}
}else{
//否则,如果间隔数tap小于0,说明是往上(左)tap张走
//打开开关
if(istrue){
//关闭开关
istrue=false;
//把 当前点击的索引值this.index 赋给替换 当前的下标num
num=this.index;
//当前滑块 对应 相应按钮 使其显色
for(var i=0;i<lis.length;i++){
lis[i].style.background="#ccc";
lis[i].style.color='black';
}
lis[num].style.background="black";
lis[num].style.color='#ccc';
//复制tap张(从最后一个子节点开始复制divs.length-1-i)添加到第一个滑块之前
//
// console.log('legnht:'+divs.length);
for(var i=0;i<Math.abs(tap);i++){
var n=divs.length-1-i;
var newNode=divs[n].cloneNode(true);
box.insertBefore(newNode,divs[0]);
}
//运动前先把box整个轮播图往左边一个滑块*tap大小,给接下来的滑动做好准备
box.style.left=(-300*Math.abs(tap))+'px';
//调用运动函数 run(运动对象[轮播图区域],运动目标,回调函数[运动完后...])
run(box,0,function(isok){
if(isok){
//删除tap次最后一个子节点,记得此时比原来多一张
for(var i=0;i<Math.abs(tap);i++){
var n=divs.length-1;
box.removeChild(divs[n]);
}
//打开开关
istrue=true;
}
});
}
}
}
}
</script>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style>
*{
padding:0;
margin:0;
}
body{
background:#F5F5F5;
}
#content{
300px;
height:200px;
background:#fff;
margin:50px auto;
position: relative;
overflow:hidden;
}
#divs{
1200px;
height:100%;
position: absolute;
}
#divs>div{
300px;
height:100%;
float:left;
text-align:center;
line-height:200px;
font-size:30px;
}
#lis{
list-style: none;
position: absolute;
right:10px;
bottom:10px;
}
#lis>li{
30px;
height:30px;
background: #ccc;
border-radius:30px;
float:left;
margin:0 6px;
text-align: center;
line-height: 30px;
}
#btns{
100%;
height:30px;
position: absolute;
top:50%;
left:0;
margin-top:-15px;
}
#btns>div{
30px;
height:50px;
background:rgba(0,0,0,.4);
float:left;
text-align: center;
line-height:50px;
font-size:22px;
font-weight: 300;
}
#btns>div:last-child{
float:right;
}
</style>
</head>
<body>
<div id="content">
<div id="divs">
<div style="background: red">1</div>
<div style="background: green">2</div>
<div style="background: blue">3</div>
<div style="background: yellow">4</div>
</div>
<ul id="lis">
<li style="background:black;color:#ccc">1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<div id="btns">
<div id="prev"><</div>
<div id="last">></div>
</div>
</div>
</body>
<!-- 引入封装好的运动函数 -->
<script src="./run.js"></script>
<script>
//整个轮播图
var content=document.getElementById('content');
//轮播图区域
var box=document.getElementById('divs');
//轮播图各个滑动对象
var divs=document.getElementById('divs').getElementsByTagName('div');
//对应每个滑动对象的按钮
var lis=document.getElementById('lis').getElementsByTagName('li');
//左prev(上一张) 右last(下一张)按钮
var prev=document.getElementById('prev');
var last=document.getElementById('last');
// 按钮下标 上一张==>num-- 下一张==>num++
var num=0;
//开关作用:当滑动对象未滑完不允许点击其他
var istrue=true;
//下一张 滑动==>封装函数
function move(){
//点击 if 成立 后 istrue 取反 ==> 开关作用
if(istrue){
//关闭开关
istrue=false;
//下一张+1,超过总数回0
num++;
if(num==lis.length){
num=0;
}
//当前滑块 对应 相应按钮 使其显色
for(var i=0;i<lis.length;i++){
lis[i].style.background="#ccc";
lis[i].style.color='black';
}
lis[num].style.background="black";
lis[num].style.color='#ccc';
//复制当前即(第一张)添加到所有滑块最后
var newNode=divs[0].cloneNode(true);
box.appendChild(newNode);
//调用运动函数 run(运动对象[轮播图区域],运动目标,回调函数[运动完后...])
run(box,-300,function(isok){
// console.log(`我拿到了定时器结束的时候返回的随机值${isok}`);
// 当到达目标后停止滑动
if(isok){
//打开开关
istrue=true;
//删除第一个子节点
box.removeChild(divs[0]);
//且让轮播图区域的left回原点0
box.style.left=0;
}
});
}
};
//点击下一张
last.onclick=move;
//自动轮播下一张
var timer1=setInterval(move,2000);
//移入整个轮播图时 停止轮播==>清除定时器
content.onmouseover=function(){
clearInterval(timer1);
}
//移出整个轮播图时 开始轮播==>开启定时器
content.onmouseout=function(){
timer1=setInterval(move,2000);
}
//点击上一张
prev.onclick=function(){
if(istrue){
//关闭开关
istrue=false;
//点击上一张-1,当等于-1时,回到最后一张==> divs长度-1
num--;
if(num==-1){
num=divs.length-1;
}
//当前滑块 对应 相应按钮 使其显色
for(var i=0;i<lis.length;i++){
lis[i].style.background="#ccc";
lis[i].style.color='black';
}
lis[num].style.background="black";
lis[num].style.color='#ccc';
//复制最后一张,添加到第一个滑块之前
var newNode=divs[divs.length-1].cloneNode(true);
box.insertBefore(newNode,divs[0]);
//运动前先把box整个轮播图往左边一个滑块大小,给接下来的滑动做好准备
box.style.left='-300px';
//调用运动函数 run(运动对象[轮播图区域],运动目标,回调函数[运动完后...])
run(box,0,function(isok){
if(isok){
//删除最后一个子节点,记得此时比原来多一张
box.removeChild(divs[divs.length-1]);
//打开开关
istrue=true;
}
});
}
}
//对应每个滑动对象的按钮 绑定点击事件
for(var i=0;i<lis.length;i++){
//给每个按钮添加索引
lis[i].index=i;
lis[i].onclick=function(){
//获取 当前点击索引this.index 减去 点击前滑块或按钮的下标num 得到 间隔数量tap
var tap=this.index - num;
//如果间隔数tap大于等于0,说明是往下(右)tap张走
if(tap>=0){
//打开开关
if(istrue){
//关闭开关
istrue=false;
//把 当前点击的索引值this.index 赋给替换 当前的下标num
num=this.index;
//当前滑块 对应 相应按钮 使其显色
for(var i=0;i<lis.length;i++){
lis[i].style.background="#ccc";
lis[i].style.color='black';
}
lis[num].style.background="black";
lis[num].style.color='#ccc';
//复制tap张(从当前即下标0开始)添加到所有滑块最后
for(var i=0;i<tap;i++){
var newNode=divs[i].cloneNode(true);
box.appendChild(newNode);
}
//调用运动函数 run(运动对象[轮播图区域],运动目标,回调函数[运动完后...])
//运动目标 = 每个滑块宽度 * tap间隔数
run(box,-300*tap,function(isok){
// console.log(`我拿到了定时器结束的时候返回的随机值${isok}`);
// 当到达目标后停止滑动
if(isok){
//打开开关
istrue=true;
//删除tap次第一个子节点
//(删除完一个,下一个下标也变成0,所以依然删除下标0的节点)
for(var j=0;j<tap;j++){
box.removeChild(divs[0]);
}
//且让轮播图区域的left回原点0
box.style.left=0;
}
});
}
}else{
//否则,如果间隔数tap小于0,说明是往上(左)tap张走
//打开开关
if(istrue){
//关闭开关
istrue=false;
//把 当前点击的索引值this.index 赋给替换 当前的下标num
num=this.index;
//当前滑块 对应 相应按钮 使其显色
for(var i=0;i<lis.length;i++){
lis[i].style.background="#ccc";
lis[i].style.color='black';
}
lis[num].style.background="black";
lis[num].style.color='#ccc';
//复制tap张(从最后一个子节点开始复制divs.length-1-i)添加到第一个滑块之前
//
// console.log('legnht:'+divs.length);
for(var i=0;i<Math.abs(tap);i++){
var n=divs.length-1-i;
var newNode=divs[n].cloneNode(true);
box.insertBefore(newNode,divs[0]);
}
//运动前先把box整个轮播图往左边一个滑块*tap大小,给接下来的滑动做好准备
box.style.left=(-300*Math.abs(tap))+'px';
//调用运动函数 run(运动对象[轮播图区域],运动目标,回调函数[运动完后...])
run(box,0,function(isok){
if(isok){
//删除tap次最后一个子节点,记得此时比原来多一张
for(var i=0;i<Math.abs(tap);i++){
var n=divs.length-1;
box.removeChild(divs[n]);
}
//打开开关
istrue=true;
}
});
}
}
}
}
</script>
</html>
var timer;
function run(obj,target,callback){
timer=setInterval(function(){
var speed=(target-obj.offsetLeft)/8;
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
if(obj.offsetLeft == target ){
clearInterval(timer);
callback(true);
}else{
obj.style.left=speed+obj.offsetLeft+'px';
callback(false);
}
},30);
}