关于JS模仿分页组件
做一个小记录吧~
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
div{
background: #555;
height: 500px;
display: flex;
justify-content: center;
}
div>p{
text-align: center;
font-size: 20px;
font-weight: bold;
float: left;
background: #8a98ff;
border: 3px solid #555;
height: 200px;
width: 150px;
}
ul{
padding: 0;
position: relative;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
overflow: hidden;
list-style: none;
border: 1px solid #c1c1c1;
display: inline-block;
}
li{
float: left;
padding: 10px;
color: #273346;
font-size: 15px;
cursor: pointer;
}
li:hover{
font-weight: bold;
background: crimson;
}
.active{
font-weight: bold;
background: crimson;
}
</style>
</head>
<body>
<div>
</div>
<ul>
</ul>
<script>
//定义变量
let data = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24],
div = document.getElementsByTagName('div')[0],
currentPage = 1,
pageCount = 2,
list = null,
li = null;
function paginationByJS(data, div, currentPage, pageCount, list, li) {
//拿到我们的总页码
function getTotalPage(data, pageCount){
if (Math.ceil(data.length / pageCount) < 0) return console.error('getTotalPage 出现问题');
return Math.ceil(data.length / pageCount);
}
//每次都能够返回 一个包含要取到数据的索引
function getArrIndex(currentPage, data, totalPge, pageCount){
let begin, end;
if (!currentPage > 0 && !data.length && !totalPge > 0 && !pageCount > 0) {
return console.error('您传入的参数有误');
}
//当前页在头尾的情况
if (currentPage === 1) {
return (totalPge === 1)? {
begin: 0,
end: data.length - 1
} : {
begin: 0,
end: pageCount -1
}
}
if (currentPage === totalPge){
begin = ((currentPage -1) * pageCount);
end = data.length -1;
return {
begin, end
}
}
//在中间的情况
if (currentPage > 1 && currentPage < totalPge){
begin = (currentPage - 1) * pageCount;
end = currentPage * pageCount -1;
return { begin, end };
}
}
//增删类名修改
function isActive(){
//拿到目前正在作用active的元素 并且获取他的innerText
let activeBtn = document.getElementsByClassName('active')[0],
oldActiveIndex = activeBtn? parseInt(activeBtn.innerText) : null;
//如果两次点击同一个按钮则不做操作
if (oldActiveIndex === currentPage){ return; }
//若按钮存在 么此先做一个删除
if (activeBtn){ activeBtn.classList.remove('active'); }
list = Array.from(document.getElementsByTagName('li'));
//遍历添加
(list.find(i=> parseInt(i.innerText) === currentPage)).classList.add('active');
}
//返回渲染数组
function getRenderList(){
let temp = getArrIndex(currentPage, data, getTotalPage(data, pageCount), pageCount);
return data.slice(temp.begin, temp.end + 1); //slice方法取头不拿尾
}
//第一次创造列表数据
function createBtn(totalPage){
let ul = document.getElementsByTagName('ul')[0];
//每次都至少显示五个 当前 当前的前2个 当前的后2个
for (let i =1; i<=totalPage; i++){
//开头
if (i === 1){
li = document.createElement('li');li.innerText = '<';
document.getElementsByTagName('ul')[0].appendChild(li);
}
//拿到页码按钮集合
li = document.createElement('li');
li.innerText = i;
//保证至少页码为8的时候才出现省略号
if(i > 6 && totalPage > 7){
li.innerText = '...';
ul.appendChild(li);
li = document.createElement('li');li.innerText = totalPage;
ul.appendChild(li);
li = document.createElement('li');li.innerText = '>';
ul.appendChild(li);
break;
}
ul.appendChild(li);
//到头了您
if (i === totalPage){
li = document.createElement('li');li.innerText = '>';
ul.appendChild(li);
}
}
}
function btnControl(totalPage, currentPage) {
//小于7 就直接全部排出来就ok 不用搞这些花里胡哨的
if (totalPage < 8)return;
let li,
before = currentPage - 2, //头
after = currentPage + 2, //尾巴
list = document.getElementsByTagName('li'), //数据列表
arr = Array.from(list).filter((i)=>{ //实际页码改变的按钮
index = parseInt(i.innerText);
return (index !== 1 && index !== totalPage && index.toString() !== 'NaN');
}),
headFlag = list[2],
endFlag = list[list.length - 3];
//控制插入 '...'
if (currentPage > 4 && headFlag.innerText !== '...'){
li = document.createElement('li');
li.innerText = '...';
list[0].parentElement.insertBefore(li, headFlag);
}
if ((currentPage > 1) && endFlag.innerText !== '...'){
li = document.createElement('li');
li.innerText = '...';
list[0].parentElement.insertBefore(li, list[list.length - 2]); //加入之前的所以是 list.length-2
}
//控制删除 '...'
if (currentPage < 5 && headFlag.innerText === '...'){
headFlag.parentNode.removeChild(headFlag);
}
if (after + 1 >= totalPage && endFlag.innerText === '...'){
endFlag.parentNode.removeChild(endFlag);
}
//关键的控制 基于他们展示时当前页 和 头尾 在边界位置以及普通位置的情况来做考虑
//在中间的时候 以currentPage为中心 前后2格
if (before > 1 && after < totalPage){
for (let i = currentPage - 2, j = 0; i <= currentPage + 2; i++, j++){
arr[j].innerText = i;
}
}
//头碰到边界了 说明要从2开始 这个currentPage是3了
if (before === 1){
for (let i = currentPage - 1, j = 0; i <= currentPage + 3; i++, j++){
arr[j].innerText = i;
}
}
//尾巴碰到边界了 说明要从currentPage回头数三个开始,不然会生成一个和totalPage相同的page,就是bug了。
if (after === totalPage){
for (let i = currentPage - 3, j = 0; i < currentPage + 2; i++, j++){
arr[j].innerText = i;
}
}
//当前页首尾~同上
if (currentPage === 1){
for (let i = currentPage + 1, j = 0; i <= arr.length + 1; i++, j++){
arr[j].innerText = i;
}
}
if (currentPage === totalPage){
for (let i = currentPage - arr.length, j = 0; i < totalPage; i++, j++){
arr[j].innerText = i;
}
}
}
function arrowControl(target, totalPage){
let event = target || window.event;
if (event) {
target = event.target;
}
if (target) {
switch (target.innerText){
case '<': currentPage = currentPage === 1? 1 : currentPage - 1;break;
case '>': currentPage = currentPage === totalPage? totalPage : currentPage + 1; break;
case '...': break;
default: currentPage = parseInt(target.innerText);
}
}
}
function displayData() {
let arr = getRenderList(), p;//最后得到的数据
div.innerHTML = ''; //重置div内容区域
arr.forEach(i =>{
p = document.createElement('p');
p.innerText = i;
p.style.padding = '10px';
div.appendChild(p);
}); //展示一下
}
//这个是事件的监听函数
function pagination(target){
let totalPage = getTotalPage(data, pageCount);
//兼容拿到事件
arrowControl(target, totalPage);
btnControl(totalPage, parseInt(currentPage));
isActive();
displayData();
}
//首次注册生成第一页数据和分页栏
function firstInit() {
createBtn(parseInt(getTotalPage(data, pageCount)));
isActive();
displayData();
}
window.onload = function () {
firstInit();
Array.from(document.getElementsByTagName('li')).forEach(i => i.onclick = function (e) {
pagination(e)
});
}
}
paginationByJS(data, div, currentPage, pageCount, list, li)
</script>
</body>
</html>
慢慢练了!
人若无名,便可专心练剑