【JS案例】分页器——使用原生JavaScript实现

2023-10-27

   在使用vue编写完一个分页器组件后,我对分页器的底层逻辑产生了兴趣,想在此组件的基础上再深入了解一些分页器的底层逻辑,了解vue与原生js的区别。我在github上看了一些大神写的分页器,属实牛逼,之后自己也根据他们的编写逻辑,反复推敲了个七八遍,也算是对分页器的逻辑掌握的差不多了,以下则是小编对原生js编写的一些体会。
   首先我们需要明白在编写js时,我们需要在页面中创建哪些标签?标签应该赋予什么属性?分页器需要哪些数据?需要哪些函数?函数需要传哪些参数?总之,需要考虑的问题非常多,从构建到渲染再到功能实现都需要亲力亲为的。

页面构建思路:
   所有按钮用a标签表示,全部放在一个div盒子中
   点击切换的按钮有正常使用的属性值(prevPage和nextPage)和禁用属性值(disabled)
   数值页面按钮有选中时的属性值(current)和未选中的属性值

创建出来的html和css代码如下:
html代码:

<div class="page"></div>

css代码:

        a {
            text-decoration: none;
        }

        .page {
            display: table;
            margin: 100px auto;
        }

        .page a {
            cursor: default;
            display: inline-block;
            color: #00C9A6;
            background-color: #D9F7F2;
            height: 25px;
            font-size: 10pt;
            line-height: 25px;
            padding: 0 9px;
            border: 1px solid #D9F7F2;
            margin: 0 2px;
            border-radius: 4px;
            vertical-align: middle;
        }

        .page a:not(.disabled):not(.current):hover {
            border: 1px solid #00C9A6;
            cursor: pointer;
        }

        .page a.current {
            display: inline-block;
            font-size: 10pt;
            height: 25px;
            line-height: 25px;
            padding: 0 9px;
            margin: 0 2px;
            color: #fff;
            background-color: #00C9A6;
            border: 1px solid #00C9A6;
            border-radius: 4px;
            vertical-align: middle;
        }

        .page a.disabled {
            display: inline-block;
            font-size: 10pt;
            height: 25px;
            line-height: 25px;
            padding: 0 9px;
            margin: 0 2px;
            color: #ddd;
            background: #D9F7F2;
            border: 1px solid #D9F7F2;
            border-radius: 4px;
            vertical-align: middle;
            cursor: no-drop;
        }

功能实现思路:
   创建一个分页器函数(Pagination),在它的原型链上编写分页器的功能函数,这样写的好处是可以让所有的对象都能共享原型上的方法,通过构造函数生成的实例所拥有的方法都指向一个函数的索引,节省内存
   创建分页器所需要的数据,并存放在一个对象上(pages)。
      pageCount:页面总数
      size:单页面数据量
      pageNo:当前页
      total:总数据量
   创建函数:
      初始化数据的方法(init):参数(pages)
         功能:将要使用的数据在init中初始化,并调用renderPage传入pages对象完成构建分页器
      构建页面的方法(renderPage):参数(pages对象)
         功能:构建分页器按钮,并调用switchPage实现切换功能
      切换页面的方法(switchPage):无参数
         功能:实现点击切换功能,调用gotoPage函数实现数值按钮的点击切换效果
      跳转页面的方法(gotoPage):参数(current)
         功能:根据传入的current值跳转到对应的页面

创建出来的js代码如下:

function Pagination(obj){
            this.init(obj)
        }
        Pagination.prototype={
            pages:{
                pageCount:0,//页面总数
                size:10,//单页面数据量
                pageNo:1//当前页
            },
            //初始化页面数据,参数:obj
            init:function(obj){
                var pages=this.pages
                pages.total=obj.total//总数据量
                obj.pageCount=Math.ceil(obj.total/obj.size)//总页码数
                pages.container=obj.container//外部容器
                pages.pageNo=obj.pageNo//当前页
                pages.pageCount=obj.pageCount//总页码数
                pages.eleHtml=obj.eleHtml//标签内部值
                pages.prevPage=obj.prevPage || 'prevPage'//上一页按钮
                pages.nextPage=obj.nextPage || 'nextPage'//下一页按钮
                this.renderPage(pages)
            },
            //构建页面,参数:args
            renderPage(args){
                var pageContainer=this.selectEle(args.container)
                var pageStr='',start,end
                //构建左侧点击按钮
                if(args.pageNo>1){
                    pageStr=`<a class="prevPage">上一页</a>`
                }else{
                    pageStr=`<a class="disabled">上一页</a>`
                }
                //构建中间页面按钮区域
                if(args.pageCount<6){//当总页码数小于6时
                    for(start=0;start<args.pageCount;start++){
                        end=start+1
                        if(end==args.pageNo){
                            pageStr+='<a class="current">'+end+'</a>'
                        }else{
                            pageStr+='<a>'+end+'</a>'
                        }
                    }
                }else{//当总页码大于等于6时
                    start=args.pageNo-1//确认遍历的起始位置为当前页的前一页
                    end=args.pageNo+1//确认遍历的结束位置为当前页的后一页
                    if(args.pageNo>2){pageStr+='<a>'+1+'</a>'}//当前页大于2时,将页面1按钮写死
                    else {end =4}//当前页小于等于2时,将遍历的结束位置写死为4
                    if(args.pageNo>args.pageCount-3){start=args.pageCount-3}//当前页为最后四个页面时,将遍历的起始位置写死为倒数第四个页面值
                    if(args.pageNo>3){pageStr+='<a>...</a>'}//当前页大于第三个页面时,将省略号按钮展现出来
                    //对中间按钮进行遍历
                    for(;start<=end;start++){
                        if(start<=args.pageCount && start>0){
                            if(start==args.pageNo){
                                pageStr+='<a class="current">'+start+'</a>'
                            }else{
                                pageStr+='<a>'+start+'</a>'
                            }
                        }
                    }
                    if(args.pageNo<args.pageCount-2){pageStr += '<a>...</a>'}//当前页面小于倒数第三个页面时,将省略号按钮展现出来
                    if(args.pageNo<args.pageCount-1){pageStr+='<a>'+args.pageCount+'</a>'}//当前页面小于倒数第二个页面,将最后的页面按钮锁死
                }
                //构建右侧按钮
                if(args.pageNo<args.pageCount){
                    pageStr+=`<a class="nextPage">下一页</a>`
                }else{
                    pageStr+=`<a class="disabled">下一页</a>`
                }
                pageContainer.innerHTML=pageStr
                this.switchPage()
            },
            //切换页面
            switchPage(){
                var pages=this.pages,g=this
                var aList=this.selectEle(pages.container+" a",true)//获取所有的a标签
                var current//定义一个当前页的标识
                //对所有的a标签遍历,绑定点击事件
                for(i in aList){
                        if(i<aList.length){
                            aList[i].addEventListener("click",function(){
                            var eleHtml=this.innerHTML//定义一个属性值来获取数字按钮
                            if(this.className==pages.prevPage){
                                pages.pageNo>1 && (pageNo=pages.pageNo-1)
                            }else if(this.className==pages.nextPage){
                                pages.pageNo<pages.pageCount && (pageNo=pages.pageNo+1)
                            }else{
                                pageNo=parseInt(eleHtml)
                            }
                            pageNo && g.gotoPage(pageNo)
                        })
                    }
                }
            },
            //跳转页面,参数:current
            gotoPage(current){
                this.pages.pageNo=current
                this.renderPage(this.pages)
            },
            //获取页面元素
            selectEle(select,all){
                return all ? document.querySelectorAll(select) : document.querySelector(select)
            }
        }
        var p=new Pagination({
            container: '.page',
            size: 10,
            pageNo: 1,
            total: 100
        })

代码解释:
   实现该分页器的主要逻辑在renderPage函数中,在构建的时候,我们要考虑到当页面数据发生变化时,其样式也要随之变化
      (1)首先构建左侧上一页按钮以及右侧下一页按钮,如果当前页面大于1或者小于页码最后一页,两个按钮正常使用,否则则禁用两个按钮
      (2)构建中间的数字按钮
         (2.1)总页码数小于6时,直接遍历展现出所有的数字按钮
         (2.2)总页码数大于6时,令起始值为当前的页码数-1,结束值为当前的页码数+1,再遍历出所有的数字按钮
            (2.2.1)当前页大于第二页或者当前页小于倒数第二个页面,分别将1按钮以及最后一个按钮写死。如果当前页小于等于2时,或者当前页为最后四个页面时,为了保证展示的按钮有三个,我们需要将初始值或者结束值写死
            (2.2.2)当前页大于第三页或者当前页小于倒数第三个页面,分别展示左侧和右侧的省略号按钮

最后我们产生的页面如图所示:
在这里插入图片描述

通过对分页器采用原生js以及用vue,相比较之下我体会到了vue的优势在于:
   1.提高了代码的可复用性,以及对代码的维护比较方便,例如,如果我们想添加一个输入框去选择我们想要跳转的页面,在vue中直接添加一个组件,而在原生js中我们需要在构建页面的函数中添加构建输入框的代码,维护性很差。
   2.vue将一些常用的js操作封装起来供我们使用,例如v-for就是对js中的for循环进行封装,使用起来更加简便。
   3.页面的灵活性更强,例如标签的类名我们可以动态进行赋值来应对页面的数据变化产生相应的样式变化。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【JS案例】分页器——使用原生JavaScript实现 的相关文章

随机推荐

  • hadoop集群配置

    一个具体的配置 这里只搭建一个三台主机的小机群 10 37 128 2 master namenode jobtracker master 主机名 10 37 128 3 salve datanode tasktracker slave1
  • 在服务器上部署 Nginx 并设置图片服务器

    当您在服务器上部署 Nginx 并设置图片服务器时 以下是大致的步骤 安装 Nginx 使用适用于您的操作系统的包管理器安装 Nginx 编辑 Nginx 配置文件 找到 Nginx 的配置文件 通常位于 etc nginx nginx c
  • matplotlib柱状图给指定的柱换颜色_Python全栈之路-15-matplotlib

    本文jupyter notebook 地址 github com import numpy as np import pandas as pd import matplotlib import matplotlib pyplot as pl
  • Redis持久化RDB与AOF

    前言 我们知道Redis是一款内存服务器 就算我们对自己的服务器足够的信任 不会出现任何软件或者硬件的故障 但也会有可能出现突然断电等情况 造成Redis服务器中的数据失效 因此 我们需要向传统的关系型数据库一样对数据进行备份 将Redis
  • MySQL完整笔记

    注 本篇大部分内容都是尚硅谷mysql课程的笔记 如果需要课程以及源码 请至官网下载 下载地址 数据库 介绍 1 概念 1 DB 数据库 保存一组有组织的数据的容器 2 DBMS 数据库管理系统 又称为数据库软件 产品 用于管理DB中的数据
  • double类型(浮点数)是否相等的判断方法

    浮点数不精确 计算机内部无法用二进制的小数来精确的表达 public class Tesz public static void main String args double a 0 1 float c 0 1f System out p
  • MixFormer步骤流程概述

    参考图 Stage1 1 输入 模板 在线模板 搜索三组图像 2 为每个输入添加位置编码 实际上是nn Conv2d 通道3 gt 64 卷积核大小 7 7 步长 4 4 填充 2 2 的卷积操作 然后归一化 3 模板 在线模板和搜索做拼接
  • 二次函数求根c语言

    include
  • mac电脑 安装homebrew、nvm、node、nrm

    安装homebrew bin zsh c curl fsSL https gitee com cunkai HomebrewCN raw master Homebrew sh brew v 查看版本号 根据提示 继续执行 不然之后安装nvm
  • Linux正向区域dns搭建

    挂载光盘使用本地yum源文件 root www yum repos d mv repo bak root www yum repos d cd mnt root www mnt mkdir cdrom root www mnt mount
  • Java常用集合类、接口

    在Java中有一套设计优良的接口和类组成了Java集合框架 使程序员操作成批的数据或对象元素极为方便 所有的Java集合都在java util包中 1 List接口及其实现类 List接口继承于Collection接口 List接口及其实现
  • Django视图学习——在视图中使用模型

    视图不仅可以获取客户端长传的数据 还可以通过模型访问后台的数据库 本文介绍以下内容 1 在视图中输出模型数据 2 数据分页 1 在视图中输出模型数据 任务 定义一个模型 然后通过该模型范围访问数据库 1 在项目子文件夹chapter5中添加
  • go-gin 自定义应用metrics

    文章目录 前言 一 gin添加go运行时metrics 1 创建一个gin server 2 创建一个metrics的路由 3 启动服务 4 查看结果 metrics页面 pprof页面 二 gin自定义应用程序metrics 官方库示例
  • 在python环境下使用selenium + chromedriver截屏网页

    在python环境下使用selenium和chromedriver工具 自动将网页内容进行截屏保存 安装 selenium比较简单 如下即可 pip install selenium 据说 chromedriver的版本一定要与Chrome
  • 顺序表起步

    时间限制 1000ms 内存限制 256MB 1 按照课本 编写顺序表及其基本运算 顺序表定义使用以下代码 typedef int datatype 结点的数据类型 假设为int const int maxsize 100 最大表长度 假设
  • fstream、ifstream、ofstream和stringstream

    ifstream ifstream 是 C 标准库中用于文件读取的输入流类之一 用于从文件中读取数据 可以通过打开文件并将其与 ifstream 对象绑定 然后使用输入操作符 gt gt 从文件中读取数据 代码示例 include
  • pgsql删除表中所有数据_PostgreSQL数据库中的表和数据(Tables & Data)

    照顾好你的数据 数据库也会照顾你 保持数据库的整洁 查询起来也会更快 应用也会少些错误 半夜被叫醒解决数据问题并不酷 接下来 就和章郎虫博主一起来了解postgresql的表和数据吧 一 选择一个好的数据库对象名 Choosing good
  • Cascade-MVSNet CVPR-2020 学习笔记总结 译文 深度学习三维重建

    文章目录 4 Cascade MVSNet CVPR 2020 4 0 主要特点 4 1 背景介绍 4 2 代价体构造回顾 4 3 Cascade MVSNet 4 4 Loss的设置 4 5 Cascade MVSNet实战操作 4 6
  • echarts图表,利用仪表盘类型变换成环形渐变图

    使用仪表盘类型图表type gauge 变换成以上图片样式 实现环形图的渐变以及背景环 1 计算当前数据占总数的比例 从而得出当前环开始角度和结束角度 目前上图中开始角度都是0 结束角度通过数据占比得到 当前数据 三个数和 360 得到结束
  • 【JS案例】分页器——使用原生JavaScript实现

    在使用vue编写完一个分页器组件后 我对分页器的底层逻辑产生了兴趣 想在此组件的基础上再深入了解一些分页器的底层逻辑 了解vue与原生js的区别 我在github上看了一些大神写的分页器 属实牛逼 之后自己也根据他们的编写逻辑 反复推敲了个