原生翻页器,了解一下?

1,619 阅读5分钟

之前用到翻页器,全部是基于别人写好的插件或者依赖;今天有时间来自己写个简单的,还是有点逻辑的,由于时间仓促,还有很多需要完善的地方,如有问题,请指出,谢谢;源代码地址:Github,欢迎Star! 个人原创,转载请注明出处,谢谢!

1、实现原理及代码实现

<ul id="ul">
	<!-- 此处可自定义显示li的数量 -->
	<li></li><li></li><li></li><li></li><li></li>
</ul>
<div id="but">
	<a id="first" href="javascript:(0)">首页</a>
	<a id="left" href="javascript:(0)">上一页</a>
	<div id="btns">
	<div class="btn">1</div>
	</div>
	<a id="right" href="javascript:(0)">下一页</a>
	<a id="foot" href="javascript:(0)">尾页</a>
</div>
  • 首先写出基本的html代码,如上;然后分析实现原理:
const arr = [];
let [ul,btns,but,left,right,first,foot] =  
[getId('ul'),getId('btns'),getId('but'),getId('left'),getId('right'),getId('first'),getId('foot')],
    index = 0,
    number = 5,//尽量设置成奇数,美观对称
    lis = ul.getElementsByTagName('li'),
    as = btns.getElementsByTagName('div');
  • 初始化

自定义一些用来显示的数组 arr ;
设置index为0,index就是当前显示的页面索引(0就是第一页);
设置翻页显示数字的数量 number ,此处我默认为5,尽量设置成奇数,这样显示翻页数字时是对称的,当然可以让用户自己设置;

for(let i = 0;i < (Math.ceil(arr.length / lis.length) - 1);i++){
	let s = i + 2,
	 	newNode = document.createElement('div');
	newNode.innerHTML = s;
	btns.appendChild(newNode);
}
action();
// 利用es6 的语言给各个翻页器按钮绑定事件
for(let i = 0; i < as.length; i++){
	as[i].onclick = function(){
	    index = i;
	    action();
	}
}
  • 根据需要显示数据的数量和单页面显示数量进行计算回出现多少页数据;并将每一个翻页数字按钮绑定点击事件;

计算显示页数时,为什么计算是 Math.ceil(arr.leng / lis.length) - 1 ?
需要严谨考虑边缘情况,当一个页面显示 5 天数据时,有6 ~ 10 条时,应该只有两页;所以此处的数据时整倍数时应该和前面一个倍数超过的部分合并,就是按倍数来分:(0,5],(5,10]...所以就找到了规律,相除再向上取整,再减一,因为已经显示一个第一页。(此处切记不能直接用parseInt(arr.length / lis.length),我已经踩过此坑)

  • 然后再将上一页、下一页、首页、尾页 等绑定相应的事件,这些点击事件中逻辑,我相信大家都能一眼看懂;
if(as.length > number){
	let num_mid = parseInt(number/2)+1;
	if(index < num_mid){ // 头
    	for(let i = 0; i < as.length; i++){
    	    if(i < number){
   	            as[i].style.display = 'inline-block';
   	        }
    	}
    }else if(index >= num_mid && index < as.length - num_mid){ // 中间
    	for(let i = 0; i < as.length; i++){
    	    if(i >= (index - num_mid + 1) && i < (index - num_mid + 1 + number)){
    	        as[i].style.display = 'inline-block';
    	    }
    	}
    }else if(index >= as.length - num_mid){ // 尾
    	for(let i = 0; i < as.length; i++){
    	    if(i >= as.length - number){
    	        as[i].style.display = 'inline-block';
    	    }
    	}
    }
}
  • 此处我截取了action()函数中控制显示数量的部分;此部分通过用户设置翻页显示数字的数量 number 和页面总数量设置完善逻辑;

首先只有页面总数量大于用户设置的数量时才会执行;
我先取用户设置数量 number 的中间值 num_mid ;当前显示的页面索引 index(从0开始) 小于 num_mid 时,就只显示前 number 个按钮就行;
as.length - num_mid 是页面总数量除掉中间值 num_mid ;当页面索引值 index 大于此值时,就只显示总数据后 number 个按钮数据;
首尾的范围取到了,中间的取值范围就水到渠成了;页面按钮显示的第一个值应该是从 index - (num_mid - 1) 开始,这就是为什么在设置时建议设置成偶数,因为要让当前页数左右可选的数量相同且对称; 取到第一个值,然后就连续取 number 个按钮进行显示;

for(let i = 0; i < as.length; i++){
    as[i].className = '';
}
as[index].className = 'btn';
for(let i = 0; i < lis.length; i++){
    if(i + lis.length * index < arr.length){
    	lis[i].style.display = 'block';
    	lis[i].innerHTML = arr[i + lis.length * index];
    }else{
    	lis[i].style.display = 'none';
    }
}
  • 将所有的页面显示数量的class名清除,然后在被点击的第 index 个按钮加上区分当前按钮上的class名,这样就能看出当前页面显示处于第几页;
    后面就是根据用户操作要显示第 index 页数据时,进行筛选然后显示相对应的数据到页面;

比喻一页面需要显示7条数据,就需要通过页面索引值 index 去寻找对应的7条数据;通过循环 i + lis.length * index 就可以得到相应的数据;
当通过循环得到数量大于数据总数量时(边缘化),就需要特殊处理,我这里是将其进行隐藏;

  • 最后贴上效果图(虽然很丑):
    效果图
    效果图

2、拓展改进

  • 页面数据显示数量和翻页数字的显示数量可以让用户输入去控制,页面样式美观等都可以进行优化;
  • 按钮数量可以默认不写一个第一页在那里,当没有数据时可以 隐藏/移除 整个翻页器;
  • 页面可以再加一个让用户输入想进入那一页,其实就是设置 index 的值;
  • 有兴趣的可以进行封装,谢谢!