本文主要是介绍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 "<<";case "prev":return "<";case "next":return ">";case "last":return ">>";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源码解读的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!