bootstrap-paginator源码解读

2023-11-02 22:48

本文主要是介绍bootstrap-paginator源码解读,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 

收获:

1.总架构:

       首先创建BootstrapPaginator构造函数,prototype赋值方法,实现页面的渲染,通过自调用匿名函数封装BootstrapPaginator类的方法,对外不提供修改及调用接口,onPageClicked方法用来改变页码的显示状况;

       再在$.fn.BootstrapPaginator内部new出一个BootstrapPaginator实例,构成jquery插件,默认配置项作为$.fn.BootstrapPaginator的属性存在,包括前后首尾页的显示文本、提示层文本、尺寸对齐等样式状况、以及onPageClicked、onPageChanged方法,onPageClicked修改页面显示状况,onPageChanged用于前后台的数据交互,因为BootstrapPaginator类和$.fn.BootstrapPaginator插件没有继承、相等关系,两个同名的onPageClicked方法也不会起冲突,通过不同的事件绑定分别调用两个同名方法。

 

2.BootstrapPaginator类的构造:

       init方法初始化,构造函数当即执行该方法,该方法内部调用setOptions调用配置项;

       setOptions设置配置项,调用listen方法绑定事件、render方法渲染页面;

       listen方法绑定BootstrapPaginator类的onPageClicked方法以及$.fn.BootstrapPaginator插件中的onPageClicked、onPageChanged方法;

       render方法创建包裹元素ul,设置尺寸、对齐方式,调用builPageItem方法判断前一页、后一页、首页、尾页、页码的显示情况,创建对应li及a子元素;

       buildPageItem方法创建li、a子元素,添加li、a的文本内容、提示层,a元素中绑定BootstrapPaginator类的onPageItemClicked方法,以此改变页面样式,或者通过跳链接的方式实现页面内容的切换,替代前后台数据交互;

       onPageItemClicked方法通过触发page-clicked事件调用BootstrapPaginator类的onPageClicked方法以及$.fn.BootstrapPaginator插件中的onPageClicked方法

       onPageClicked方法通过点击分页区域改变页面样式,调用showFirst、showLast、showNext、showPrev、show方法实现;

       showFirst、showLast、showNext、showPrev方法通过调用getPages方法以数组形式记录页码显示状况,调用show方法设置当前页、渲染页面、绑定page-changed事件;

       getPages方法以数组形式记录页码的显示状况,并且以数组的属性记录当前页、前一页、后一页、首页、尾页、显示页码的个数,方便调用,以作判断;

       show方法设置当前页、调用render方法渲染页面、绑定page-changed事件,触发onPageChanged方法;

       getValueFromOption方法,参数的第一项为函数的时候,将参数的其余项传入该函数构造输出,否则直接将参数输出。

       getValueFromOption方法、类的设计较有深意。

 

3.jquery的新认识:

       $.on("eventtype",[selector],[data],fn)...selector事件捕获阶段查询的子节点,data是传入event.data中的数据;

       $.proxy(fn,content)...fn的作用域改成content,并返回fn;

       $("element").on("eventtype",fn)...绑定事件;

       $("element").trigger("eventtype",[arguments])触发事件,并传入arguments参数;

       $("element").data()...获取或设置元素的data数据,该数据添加到dom元素中不会在元素的属性中显示;

       typeof data...自动截取data的第一项作判断;

       data.apply(this,arguments)...data的第一项为函数的时候,执行apply方法,改变该函数的作用域,设置传入的参数。

 

4.插件的使用:

       版本为2的时候页面元素只能是div,版本为3的时候只能是ul

       onPageClicked用于改变页面样式,onPageChanged实现数据交互

       插件提供了跳连接的方式实现页面交互,可通过修改配置项的pageUrl函数

itemTexts函数修改显示文本,tooltipTitles修改提示文本

 

实例:

html:

<ul id="pagination"></ul> 

js:

var options={currentPage: 1,totalPages: 25,numberofPages: 5,itemTexts: function(type, page, current) {switch (type) {case "first":return "第一页";case "prev":return "上一页";case "next":return "下一页";case "last":return "最后一页";case "page":return page;}},onPageChanged: function (event,lastpage, currentpage) {$.post("",{page:currentpage},function(data) {});}, pageUrl: function (type,page, currentpage) {return "/***.htm?currentpage="+page}, //跳链接的方式
};
$("#pagination").bootstrapPaginator(options);

 

 

5.插件存在的缺点,或者预留的可扩展部分

通过清除包裹元素的样式,再调用containerClass函数的方式添加样式未免多此一举。

余不赘述

 

6.源码:

(function ($) {"use strict"; //先创建分页的构造函数,作为公有方法,再将该构造函数通过new方法赋在$.fn.bootstrapPaginator内部形成jquery插件//默认项在$.fn.bootstrapPaginator.defaults中定义,包含显示前一页的显示文本、是否显示以及提示文字,可修改部分var BootstrapPaginator = function (element, options) {this.init(element, options);},old = null;BootstrapPaginator.prototype = {init: function (element, options) {this.$element = $(element);var version = (options && options.bootstrapMajorVersion) ? options.bootstrapMajorVersion : $.fn.bootstrapPaginator.defaults.bootstrapMajorVersion,id = this.$element.attr("id");// 版本2中容器元素只能为div,版本3容器元素只能为ulif (version === 2 && !this.$element.is("div")) {throw "in Bootstrap version 2 the pagination must be a div element. Or if you are using Bootstrap pagination 3. Please specify it in bootstrapMajorVersion in the option";} else if (version > 2 && !this.$element.is("ul")) {throw "in Bootstrap version 3 the pagination root item must be an ul element."}this.currentPage = 1;this.lastPage = 1;this.setOptions(options);this.initialized = true;},//配置项,绑定事件、渲染页面setOptions: function (options) {this.options = $.extend({}, (this.options || $.fn.bootstrapPaginator.defaults), options);this.totalPages = parseInt(this.options.totalPages, 10);this.numberOfPages = parseInt(this.options.numberOfPages, 10);if (options && typeof (options.currentPage)  !== 'undefined') {this.setCurrentPage(options.currentPage);}this.listen();this.render();if (!this.initialized && this.lastPage !== this.currentPage) {this.$element.trigger("page-changed", [this.lastPage, this.currentPage]);}},// 绑定事件监听函数,page-clicked事件触发onPageClicked方法,page-changed事件触发onPageChanged方法// this.onPageClicked调用paginator类的方法,this.options.onPageClicked调用配置项中的方法// listen: function () {this.$element.off("page-clicked");this.$element.off("page-changed");if (typeof (this.options.onPageClicked) === "function") {this.$element.bind("page-clicked", this.options.onPageClicked);}if (typeof (this.options.onPageChanged) === "function") {this.$element.on("page-changed", this.options.onPageChanged);}this.$element.bind("page-clicked", this.onPageClicked);},destroy: function () {this.$element.off("page-clicked");this.$element.off("page-changed");this.$element.removeData('bootstrapPaginator');this.$element.empty();},//根据页码显示状况和当前页进行渲染,trigger触发onPageChanged函数,传入当前页和前一次当前页两个参数show: function (page) {this.setCurrentPage(page);this.render();if (this.lastPage !== this.currentPage) {this.$element.trigger("page-changed", [this.lastPage, this.currentPage]);}},//showNext、showPrev、showFirst、showLast页码显示状况showNext: function () {var pages = this.getPages();if (pages.next) {this.show(pages.next);}},showPrevious: function () {var pages = this.getPages();if (pages.prev) {this.show(pages.prev);}},showFirst: function () {var pages = this.getPages();if (pages.first) {this.show(pages.first);}},showLast: function () {var pages = this.getPages();if (pages.last) {this.show(pages.last);}},//通过on方法向onPageItemClicked方法中的event.data传递参数,再通过trigger触发page-clicked事件,调用onPageClicked方法,实现参数传递//onPageClicked修改页面显示状况,onPageChanged可以用来前后台的数据交互,参数为event,lastpage、currentpageonPageItemClicked: function (event) {var type = event.data.type,page = event.data.page;this.$element.trigger("page-clicked", [event, type, page]);},onPageClicked: function (event, originalEvent, type, page) {var currentTarget = $(event.currentTarget);switch (type) {case "first":currentTarget.bootstrapPaginator("showFirst");break;case "prev":currentTarget.bootstrapPaginator("showPrevious");break;case "next":currentTarget.bootstrapPaginator("showNext");break;case "last":currentTarget.bootstrapPaginator("showLast");break;case "page":currentTarget.bootstrapPaginator("show", page);break;}},// 根据版本号判断是否添加包裹元素ul,为该ul添加pagination类,设定大小、对齐方式// 包裹元素根据first、next、prev、last、page类型,通过buildPageItem创建li、a子元素render: function () {// 容器元素的类会被清空,需要优先记录,添加完pagination类后再放回var containerClass = this.getValueFromOption(this.options.containerClass, this.$element),size = this.options.size || "normal",alignment = this.options.alignment || "left",pages = this.getPages(),listContainer = this.options.bootstrapMajorVersion === 2 ? $("<ul></ul>") : this.$element,listContainerClass = this.options.bootstrapMajorVersion === 2 ? this.getValueFromOption(this.options.listContainerClass, listContainer) : null,first = null,prev = null,next = null,last = null,p = null,i = 0;listContainer.prop("class", "");listContainer.addClass("pagination");switch (size.toLowerCase()) {case "large":case "small":case "mini":this.$element.addClass($.fn.bootstrapPaginator.sizeArray[this.options.bootstrapMajorVersion][size.toLowerCase()]);break;default:break;}if (this.options.bootstrapMajorVersion === 2) {switch (alignment.toLowerCase()) {case "center":this.$element.addClass("pagination-centered");break;case "right":this.$element.addClass("pagination-right");break;default:break;}}this.$element.addClass(containerClass);this.$element.empty();if (this.options.bootstrapMajorVersion === 2) {this.$element.append(listContainer);listContainer.addClass(listContainerClass);}this.pageRef = [];if (pages.first) {first = this.buildPageItem("first", pages.first);if (first) {listContainer.append(first);}}if (pages.prev) {prev = this.buildPageItem("prev", pages.prev);if (prev) {listContainer.append(prev);}}for (i = 0; i < pages.length; i = i + 1) {p = this.buildPageItem("page", pages[i]);if (p) {listContainer.append(p);}}if (pages.next) {next = this.buildPageItem("next", pages.next);if (next) {listContainer.append(next);}}if (pages.last) {last = this.buildPageItem("last", pages.last);if (last) {listContainer.append(last);}}},// 容器元素下插入li子元素,当前页添加active类,首页、前一页、后一页、尾页显示文本、提示框,绑定点击事件buildPageItem: function (type, page) {var itemContainer = $("<li></li>"),itemContent = $("<a></a>"),text = "",title = "",//itemContainerClass记录当前页的激活状态itemContainerClass = this.options.itemContainerClass(type, page, this.currentPage),itemContentClass = this.getValueFromOption(this.options.itemContentClass, type, page, this.currentPage),tooltipOpts = null;switch (type) {case "first"://判断是否显示跳转到首页,根据当前页是否首页进行判断if (!this.getValueFromOption(this.options.shouldShowPage, type, page, this.currentPage)) { return; }text = this.options.itemTexts(type, page, this.currentPage);title = this.options.tooltipTitles(type, page, this.currentPage);break;case "last":if (!this.getValueFromOption(this.options.shouldShowPage, type, page, this.currentPage)) { return; }text = this.options.itemTexts(type, page, this.currentPage);title = this.options.tooltipTitles(type, page, this.currentPage);break;case "prev":if (!this.getValueFromOption(this.options.shouldShowPage, type, page, this.currentPage)) { return; }text = this.options.itemTexts(type, page, this.currentPage);title = this.options.tooltipTitles(type, page, this.currentPage);break;case "next":if (!this.getValueFromOption(this.options.shouldShowPage, type, page, this.currentPage)) { return; }text = this.options.itemTexts(type, page, this.currentPage);title = this.options.tooltipTitles(type, page, this.currentPage);break;case "page":if (!this.getValueFromOption(this.options.shouldShowPage, type, page, this.currentPage)) { return; }text = this.options.itemTexts(type, page, this.currentPage);title = this.options.tooltipTitles(type, page, this.currentPage);break;}itemContainer.addClass(itemContainerClass).append(itemContent);// a元素中绑定onPageItemClicked事件,并通过on方法以及$.proxy方法传递参数,on方法的第三个参数是给event.data添加的参数// 分页通过前后端以ajax形式传递数据的方式实现跳转itemContent.addClass(itemContentClass).html(text).on("click", null, {type: type, page: page}, $.proxy(this.onPageItemClicked, this));// 分页通过跳链接的方式实现跳转if (this.options.pageUrl) {itemContent.attr("href", this.getValueFromOption(this.options.pageUrl, type, page, this.currentPage));}// 提示默认采用浏览器自带提示框,也可以引进bootstrapTooltip插件实现提示框if (this.options.useBootstrapTooltip) {tooltipOpts = $.extend({}, this.options.bootstrapTooltipOptions, {title: title});itemContent.tooltip(tooltipOpts);} else {itemContent.attr("title", title);}return itemContainer;},// 设置当前页,并记录上一次的当前页,避免用户重复点击同一页面触发事件setCurrentPage: function (page) {if (page > this.totalPages || page < 1) {throw "Page out of range";}this.lastPage = this.currentPage;this.currentPage = parseInt(page, 10);},// 数组记录页码显示状况,数组的属性记录当前页,前一页,后一页,首页,尾页,总页数,显示页码数getPages: function () {var totalPages = this.totalPages,pageStart = (this.currentPage % this.numberOfPages === 0) ? (parseInt(this.currentPage / this.numberOfPages, 10) - 1) * this.numberOfPages + 1 : parseInt(this.currentPage / this.numberOfPages, 10) * this.numberOfPages + 1,//calculates the start page.output = [],i = 0,counter = 0;pageStart = pageStart < 1 ? 1 : pageStart;for (i = pageStart, counter = 0; counter < this.numberOfPages && i <= totalPages; i = i + 1, counter = counter + 1) {//fill the pagesoutput.push(i);}output.first = 1;if (this.currentPage > 1) {output.prev = this.currentPage - 1;} else {output.prev = 1;}if (this.currentPage < totalPages) {output.next = this.currentPage + 1;} else {output.next = totalPages;}output.last = totalPages;output.current = this.currentPage;output.total = totalPages;output.numberOfPages = this.options.numberOfPages;return output;},// 配置项中有函数,将参数传入函数输出,无函数直接输出getValueFromOption: function (value) {var output = null,args = Array.prototype.slice.call(arguments, 1);if (typeof value === 'function') {output = value.apply(this, args);} else {output = value;}return output;}};//构造jquery插件old = $.fn.bootstrapPaginator;$.fn.bootstrapPaginator = function (option) {var args = arguments,result = null;$(this).each(function (index, item) {var $this = $(item),data = $this.data('bootstrapPaginator'),//获取元素的data数据,该数据不会在页面上显示,不知何种泳衣???options = (typeof option !== 'object') ? null : option;if (!data) {data = new BootstrapPaginator(this, options);$this = $(data.$element);$this.data('bootstrapPaginator', data);return;}if (typeof option === 'string') {if (data[option]) {result = data[option].apply(data, Array.prototype.slice.call(args, 1));} else {throw "Method " + option + " does not exist";}} else {result = data.setOptions(option);}});return result;};$.fn.bootstrapPaginator.sizeArray = {"2": {"large": "pagination-large","small": "pagination-small","mini": "pagination-mini"},"3": {"large": "pagination-lg","small": "pagination-sm","mini": ""}};$.fn.bootstrapPaginator.defaults = {containerClass: "",size: "normal",alignment: "left",bootstrapMajorVersion: 3,listContainerClass: "",itemContainerClass: function (type, page, current) {return (page === current) ? "active" : "";},itemContentClass: function (type, page, current) {return "";},currentPage: 1,numberOfPages: 5,totalPages: 1,pageUrl: function (type, page, current) {return null;},onPageClicked: null,onPageChanged: null,useBootstrapTooltip: false,shouldShowPage: function (type, page, current) {var result = true;switch (type) {case "first":result = (current !== 1);break;case "prev":result = (current !== 1);break;case "next":result = (current !== this.totalPages);break;case "last":result = (current !== this.totalPages);break;case "page":result = true;break;}return result;},itemTexts: function (type, page, current) {switch (type) {case "first":return "&lt;&lt;";case "prev":return "&lt;";case "next":return "&gt;";case "last":return "&gt;&gt;";case "page":return page;}},tooltipTitles: function (type, page, current) {switch (type) {case "first":return "Go to first page";case "prev":return "Go to previous page";case "next":return "Go to next page";case "last":return "Go to last page";case "page":return (page === current) ? "Current page is " + page : "Go to page " + page;}},bootstrapTooltipOptions: {animation: true,html: true,placement: 'top',selector: false,title: "",container: false}};$.fn.bootstrapPaginator.Constructor = BootstrapPaginator;}(window.jQuery));

 

这篇关于bootstrap-paginator源码解读的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/333824

相关文章

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

MCU7.keil中build产生的hex文件解读

1.hex文件大致解读 闲来无事,查看了MCU6.用keil新建项目的hex文件 用FlexHex打开 给我的第一印象是:经过软件的解释之后,发现这些数据排列地十分整齐 :02000F0080FE71:03000000020003F8:0C000300787FE4F6D8FD75810702000F3D:00000001FF 把解释后的数据当作十六进制来观察 1.每一行数据

Java ArrayList扩容机制 (源码解读)

结论:初始长度为10,若所需长度小于1.5倍原长度,则按照1.5倍扩容。若不够用则按照所需长度扩容。 一. 明确类内部重要变量含义         1:数组默认长度         2:这是一个共享的空数组实例,用于明确创建长度为0时的ArrayList ,比如通过 new ArrayList<>(0),ArrayList 内部的数组 elementData 会指向这个 EMPTY_EL

如何在Visual Studio中调试.NET源码

今天偶然在看别人代码时,发现在他的代码里使用了Any判断List<T>是否为空。 我一般的做法是先判断是否为null,再判断Count。 看了一下Count的源码如下: 1 [__DynamicallyInvokable]2 public int Count3 {4 [__DynamicallyInvokable]5 get

工厂ERP管理系统实现源码(JAVA)

工厂进销存管理系统是一个集采购管理、仓库管理、生产管理和销售管理于一体的综合解决方案。该系统旨在帮助企业优化流程、提高效率、降低成本,并实时掌握各环节的运营状况。 在采购管理方面,系统能够处理采购订单、供应商管理和采购入库等流程,确保采购过程的透明和高效。仓库管理方面,实现库存的精准管理,包括入库、出库、盘点等操作,确保库存数据的准确性和实时性。 生产管理模块则涵盖了生产计划制定、物料需求计划、

Spring 源码解读:自定义实现Bean定义的注册与解析

引言 在Spring框架中,Bean的注册与解析是整个依赖注入流程的核心步骤。通过Bean定义,Spring容器知道如何创建、配置和管理每个Bean实例。本篇文章将通过实现一个简化版的Bean定义注册与解析机制,帮助你理解Spring框架背后的设计逻辑。我们还将对比Spring中的BeanDefinition和BeanDefinitionRegistry,以全面掌握Bean注册和解析的核心原理。

音视频入门基础:WAV专题(10)——FFmpeg源码中计算WAV音频文件每个packet的pts、dts的实现

一、引言 从文章《音视频入门基础:WAV专题(6)——通过FFprobe显示WAV音频文件每个数据包的信息》中我们可以知道,通过FFprobe命令可以打印WAV音频文件每个packet(也称为数据包或多媒体包)的信息,这些信息包含该packet的pts、dts: 打印出来的“pts”实际是AVPacket结构体中的成员变量pts,是以AVStream->time_base为单位的显

kubelet组件的启动流程源码分析

概述 摘要: 本文将总结kubelet的作用以及原理,在有一定基础认识的前提下,通过阅读kubelet源码,对kubelet组件的启动流程进行分析。 正文 kubelet的作用 这里对kubelet的作用做一个简单总结。 节点管理 节点的注册 节点状态更新 容器管理(pod生命周期管理) 监听apiserver的容器事件 容器的创建、删除(CRI) 容器的网络的创建与删除

GPT系列之:GPT-1,GPT-2,GPT-3详细解读

一、GPT1 论文:Improving Language Understanding by Generative Pre-Training 链接:https://cdn.openai.com/research-covers/languageunsupervised/language_understanding_paper.pdf 启发点:生成loss和微调loss同时作用,让下游任务来适应预训

red5-server源码

red5-server源码:https://github.com/Red5/red5-server