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

相关文章

Nacos注册中心和配置中心的底层原理全面解读

《Nacos注册中心和配置中心的底层原理全面解读》:本文主要介绍Nacos注册中心和配置中心的底层原理的全面解读,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录临时实例和永久实例为什么 Nacos 要将服务实例分为临时实例和永久实例?1.x 版本和2.x版本的区别

C++类和对象之默认成员函数的使用解读

《C++类和对象之默认成员函数的使用解读》:本文主要介绍C++类和对象之默认成员函数的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、默认成员函数有哪些二、各默认成员函数详解默认构造函数析构函数拷贝构造函数拷贝赋值运算符三、默认成员函数的注意事项总结一

MySQL的ALTER TABLE命令的使用解读

《MySQL的ALTERTABLE命令的使用解读》:本文主要介绍MySQL的ALTERTABLE命令的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、查看所建表的编China编程码格式2、修改表的编码格式3、修改列队数据类型4、添加列5、修改列的位置5.1、把列

Linux CPU飙升排查五步法解读

《LinuxCPU飙升排查五步法解读》:本文主要介绍LinuxCPU飙升排查五步法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录排查思路-五步法1. top命令定位应用进程pid2.php top-Hp[pid]定位应用进程对应的线程tid3. printf"%

解读@ConfigurationProperties和@value的区别

《解读@ConfigurationProperties和@value的区别》:本文主要介绍@ConfigurationProperties和@value的区别及说明,具有很好的参考价值,希望对大家... 目录1. 功能对比2. 使用场景对比@ConfigurationProperties@Value3. 核

8种快速易用的Python Matplotlib数据可视化方法汇总(附源码)

《8种快速易用的PythonMatplotlib数据可视化方法汇总(附源码)》你是否曾经面对一堆复杂的数据,却不知道如何让它们变得直观易懂?别慌,Python的Matplotlib库是你数据可视化的... 目录引言1. 折线图(Line Plot)——趋势分析2. 柱状图(Bar Chart)——对比分析3

Jupyter notebook安装步骤解读

《Jupyternotebook安装步骤解读》:本文主要介绍Jupyternotebook安装步骤,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、开始安装二、更改打开文件位置和快捷启动方式总结在安装Jupyter notebook 之前,确认您已安装pytho

Java中的StringUtils.isBlank()方法解读

《Java中的StringUtils.isBlank()方法解读》:本文主要介绍Java中的StringUtils.isBlank()方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录所在库及依赖引入方法签名方法功能示例代码代码解释与其他方法的对比总结StringUtils.isBl

对Django中时区的解读

《对Django中时区的解读》:本文主要介绍对Django中时区的解读方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录背景前端数据库中存储接口返回AI的解释问题:这样设置的作用答案获取当前时间(自动带时区)转换为北京时间显示总结背景设置时区为北京时间 TIM

Java中的内部类和常用类用法解读

《Java中的内部类和常用类用法解读》:本文主要介绍Java中的内部类和常用类用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录内部类和常用类内部类成员内部类静态内部类局部内部类匿名内部类常用类Object类包装类String类StringBuffer和Stri