原生js实现带运动的分页效果

时间:2022-08-25 12:27:25

本例最终效果如下图,当切换页码时,本页码内所有课程将从最后一个课程开始依次运动到底部中间的位置并消失,然后新页码内的课程依次从底部中间的位置运动到原始位置。
原生js实现带运动的分页效果

首先实现分页效果,然后将运动和分页结合。
分页效果图如下图中的③或④所示:
原生js实现带运动的分页效果

下面将以 什么情况出现首页-什么情况出现上一页-五个页码不同排布情况-什么情况出现下一页-什么情况出现尾页-总页码提示-点击页码进行切换 的思路实现该分页效果。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}

a{
text-decoration: none;
margin: 0 5px;
color: #333;
}

#div1{
width: 480px;
margin: 200px auto;
}

</style>
<script type="text/javascript">
window.onload=function(){
page({

id:'div1',
nowNum:8, //默认为1
allNum:16, //默认为5
callback:function(now,all){ //传入两个参数:当前页和总页数
alert(now+'/'+all);
}

})
}

//封装好的分页函数
function page(opt){

//判断调用时是否传入id,只在传入id的情况下使用该分页函数
if (!opt.id) {
return false;
}

var obj=document.getElementById(opt.id);
var nowNum=opt.nowNum || 1; //当前页,默认1
var allNum=opt.allNum || 5; //总页码,默认5

//看回调函数是否存在,如果存在就直接赋值,不存在则默认空
var callback=opt.callback || function(){};

//首页,仅在当前页大于等于4 且 总页码大于等于6的情况下出现‘首页’,图①
if (nowNum>=4 && allNum>=6) {
var oA=document.createElement('a');
oA.href='#1';
oA.innerHTML='首页';
obj.appendChild(oA);
}

//上一页,在当前页大于等于2的情况下出现‘上一页’,图②
if (nowNum>=2) {
var oA=document.createElement('a');
oA.href='#'+(nowNum-1);
oA.innerHTML='上一页';
obj.appendChild(oA);
}

//5个页码,分两种情况,一是总页码小于等于5,二是总页码大于5,图③和④
if (allNum<=5) { //总页码小于等于5

for (var i=1; i<=allNum; i++) {
var oA=document.createElement('a');
oA.href='#'+i;
if (nowNum==i) { //当前页页码不加[]
oA.innerHTML=i;
}else{
oA.innerHTML='['+ i +']';
}

obj.appendChild(oA);
}

}else{ //总页码大于5
for (var i=1; i<=5; i++) {

var oA=document.createElement('a');

if (nowNum<3) { //当前值小于3的情况,图⑤

oA.href='#'+i;
if (nowNum==i) {
oA.innerHTML=i;
}else{
oA.innerHTML='['+ i +']';
}

}else if (nowNum>(allNum-2)) { //当前值为最后两个数值,图⑥

oA.href='#'+(allNum+i-5);

if (nowNum==(allNum+i-5)) {
oA.innerHTML=(allNum+i-5);
}else{
oA.innerHTML='['+ (allNum+i-5) +']';
}

}else{

oA.href='#'+(nowNum-3+i);
if (i==3) {
oA.innerHTML=(nowNum-3+i);
}else{
oA.innerHTML='['+ (nowNum-3+i) +']';
}

}

obj.appendChild(oA);
}
}

//下一页,当前值不等于总页码数且总页码数大于等于2的情况下,图⑦
if ((allNum-nowNum)>=1) {
var oA=document.createElement('a');
oA.href='#'+(nowNum+1);
oA.innerHTML='下一页';
obj.appendChild(oA);
}

//尾页,当总页码比当前页至少大3,且总页码数大于等于6的情况下出现,图⑧
if ((allNum-nowNum)>=3 && allNum>=6) {
var oA=document.createElement('a');
oA.href='#'+allNum;
oA.innerHTML='尾页';
obj.appendChild(oA);
}

//总共页码
var oSpan=document.createElement('span');
oSpan.innerHTML='共 '+ allNum +' 页';
obj.appendChild(oSpan);

//执行回调函数
callback(nowNum,allNum);

//点击切换
var aA=obj.getElementsByTagName('a');
for (var i=0; i<aA.length; i++) {
aA[i].onclick=function(){ //点击哪个,则哪个href值中#后面的数值就为当前页
var nowNum=parseInt(this.getAttribute('href').substring(1));
obj.innerHTML='';

//每点击一次,就重新执行一次
page({
id:opt.id,
nowNum:nowNum,
allNum:allNum,
callback:callback
})

return false;

}
}

}
</script>
</head>
<body>
<div id="div1">
<!--<a href="#1">首页</a>
<a href="#6">上一页</a>
<a href="#5">[5]</a>
<a href="#6">[6]</a>
<a href="#7">7</a>
<a href="#8">[8]</a>
<a href="#9">[9]</a>
<a href="#8">下一页</a>
<a href="#20">尾页</a>
<span>共20页</span>-->

</div>
</body>
</html>

分页效果实现后,将运动效果放到分页效果的回调函数里,就可以实现带运动的分页效果。运动效果的实现分两种情况,即初始添加课程并实现定位和点击页码课程的运动切换特效。在点击页码切换课程里又分了两个步骤,即课程的收缩消失和展开显示。在收缩和展开的运动过程中由于各个课程并不是同时运动,而是单独依次运动的,所以要开启定时器,收缩结束清除定时器,同时也是下一个展开运动定时器的开始。另外,本例用到了前面文章中的运动框架Move.js。最终代码如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>

<style type="text/css">
*{ margin: 0; padding: 0;}
a{ text-decoration: none; margin: 0 5px; color: #333;}
#ul1{ width: 600px; height: 240px; list-style: none; margin: 50px auto; overflow: hidden; position: relative;}
#ul1 li{ width: 100px; height: 100px; background: olive; float: left; margin: 10px;}
#div1{ width: 320px; margin: 40px auto;}
</style>

<script src="js/Move.js" type="text/javascript" charset="utf-8"></script>

<script type="text/javascript">
window.onload=function(){

var json={ //这里用一个简单的json模拟后台传输过来的数据
"title":["课程1","课程2","课程3","课程4","课程5","课程6","课程7","课程8","课程9","课程10","课程11","课程12","课程13","课程14","课程15","课程16","课程17","课程18","课程19","课程20","课程21","课程22","课程23","课程24","课程25","课程26","课程27","课程28","课程29","课程30","课程31","课程32","课程33","课程34"]
}

var arr=[];
var iNow=9;

page({

id:'div1',
nowNum:1,
allNum:Math.ceil(json.title.length/10),
callback:function(now,all){
var num=now<all ? 10 : json.title.length-(now-1)*10; //每页显示的个数
var oUl=document.getElementById("ul1");
var aLi=oUl.getElementsByTagName('li');

if (oUl.innerHTML=='') { //首次需要添加li,后续不用添加li,只需更换li里面的内容就可以了

for (var i=0; i<num; i++) {
var oLi=document.createElement('li');
oLi.innerHTML=json.title[(now-1)*10+i]; //将json中的数据对应的添加到li中
oUl.appendChild(oLi);
}

for (var i=0; i<aLi.length; i++) {
arr.push( [aLi[i].offsetLeft,aLi[i].offsetTop] ); //将各个li的位置信息存在数组里,以便后续使用
}

for (var i=0; i<aLi.length; i++) { //将各个li改成绝对定位,并把存储好的位置信息赋给各个li的left和top
aLi[i].style.position='absolute';
aLi[i].style.left=arr[i][0]+'px';
aLi[i].style.top=arr[i][1]+'px';
aLi[i].style.margin=0;
}

}else{
var timer=setInterval(function(){ //收缩运动,从最后一个li依次往第一个开始收缩运动
startMove(aLi[iNow],{"left":250,"top":240,"opacity":0}); //这里的运动终点可以根据具体需求而定
if (iNow==0) { //第一个收缩完成后清除定时器
clearInterval(timer);
iNow=num-1; //将最后一个赋值给iNow,因为后续展开运动还是从最后一个开始
for (var i=0; i<num; i++) { //更换每个li里面的内容
aLi[i].innerHTML=json.title[(now-1)*10+i];
}
var timer2=setInterval(function(){ //开始展开运动
startMove(aLi[iNow],{"left":arr[iNow][0],"top":arr[iNow][1],"opacity":100});
if (iNow==0) { //第一个展开结束后清除定时器
clearInterval(timer2);
iNow=num-1; //将最后一个赋值给iNow,以便下一次展开收缩运动
}else{
iNow--;
}
},20)
}else{
iNow--;
}
},50)
}
}

})
}

function page(opt){

if (!opt.id) {
return false;
}

var obj=document.getElementById(opt.id);
var nowNum=opt.nowNum || 1;
var allNum=opt.allNum || 5;

//看回调函数是否存在,如果存在就直接赋值,不存在则默认空
var callback=opt.callback || function(){};

//首页
if (nowNum>=4 && allNum>=6) {
var oA=document.createElement('a');
oA.href='#1';
oA.innerHTML='首页';
obj.appendChild(oA);
}

//上一页
if (nowNum>=2) {
var oA=document.createElement('a');
oA.href='#'+(nowNum-1);
oA.innerHTML='上一页';
obj.appendChild(oA);
}

//5个页码
if (allNum<=5) {

for (var i=1; i<=allNum; i++) {
var oA=document.createElement('a');
oA.href='#'+i;
if (nowNum==i) {
oA.innerHTML=i;
}else{
oA.innerHTML='['+ i +']';
}

obj.appendChild(oA);
}

}else{
for (var i=1; i<=5; i++) {

var oA=document.createElement('a');

if (nowNum<3) {

oA.href='#'+i;
if (nowNum==i) {
oA.innerHTML=i;
}else{
oA.innerHTML='['+ i +']';
}

}else if (nowNum>(allNum-2)) {

oA.href='#'+(allNum+i-5);

if (nowNum==(allNum+i-5)) {
oA.innerHTML=(allNum+i-5);
}else{
oA.innerHTML='['+ (allNum+i-5) +']';
}

}else{

oA.href='#'+(nowNum-3+i);
if (i==3) {
oA.innerHTML=(nowNum-3+i);
}else{
oA.innerHTML='['+ (nowNum-3+i) +']';
}

}

obj.appendChild(oA);
}
}

//下一页
if ((allNum-nowNum)>=1) {
var oA=document.createElement('a');
oA.href='#'+(nowNum+1);
oA.innerHTML='下一页';
obj.appendChild(oA);
}

//尾页
if ((allNum-nowNum)>=3 && allNum>=6) {
var oA=document.createElement('a');
oA.href='#'+allNum;
oA.innerHTML='尾页';
obj.appendChild(oA);
}

//总共页码
var oSpan=document.createElement('span');
oSpan.innerHTML='总共 '+ allNum +' 页';
obj.appendChild(oSpan);

//执行回调函数
callback(nowNum,allNum);

//点击切换
var aA=obj.getElementsByTagName('a');
for (var i=0; i<aA.length; i++) {
aA[i].onclick=function(){
var nowNum=parseInt(this.getAttribute('href').substring(1));
obj.innerHTML='';

page({
id:opt.id,
nowNum:nowNum,
allNum:allNum,
callback:callback
})

return false;

}
}

}
</script>
</head>
<body>
<div id="ul1"></div>
<div id="div1"></div>
</body>
</html>