背景: 因爲項目特殊性,分頁功能,後臺沒法像常規方法一樣從數據庫分頁查找數據。所以前臺會獲取所有的數據,然後進行前臺分頁。關鍵字查詢也是因爲上述原因,用的是js自帶的indexOf()方法。
使用的插件和方法:
1. ajax
2. handlerbars模板引擎
3. jquery插件開發過程
代碼結構如下:
html代碼:
<!-- 數據展示區域-->
<table>
<tbody id="margin-panel"></tbody>
</table>
<div class="page">
<ul class="pure-paginator">
<li><a class="pure-button first" href="javascript:void(0)" data-page-index="1">首頁</a></li>
<li><a class="pure-button prev" href="javascript:void(0)">上一頁</a></li>
<li class="pageBtnGroup"></li>
<!--翻頁按鈕-->
<li><a class="pure-button next" href="javascript:void(0)">下一頁</a></li>
<li><a class="pure-button last" href="javascript:void(0)" data-page-index="">尾頁</a></li>
</ul>
</div>
<!-- 所需要的模板 -->
<script id="finamceStocks-template" type="text/x-handlebars-template">
{{#each stocksdata}}
<tr>
<td>{{id}}</td>
<td>{{secCode}}</td>
<td>{{secAbbr}}</td>
<td>{{rate}}</td>
<td>{{branch}}</td>
<td>{{lastUpdateTime}}</td>
</tr>
{{/each}}
</script>
js代碼部分:
*.render = function(data){
$(".pure-paginator").paging({
data : stocksdata, /*所有數據*/
numBtnOnepage : 5, /*帶頁數的按鈕數量*/
numOnePage : 10, /*每頁顯示數據*/
btnGroupLoc : ".pageBtnGroup", /*帶頁數按鈕組容器*/
tpl : "#finamceStocks-template", /*數據展示視圖模板*/
tplParam : "stocksdata", /*視圖模板參數對象*/
dataLoc : "#margin-panel" /*數據展示容器*/
});
}
自己寫的jquery插件paging
/**
* 翻頁
* created by wangdong
* 2017/01/23
*
* 數據從0開始計數
* 頁數從1開始計數
* 當前對象是所有按鈕組(包括上一頁、下一頁、首頁、尾頁)
*
*/
;(function($){
jQuery.fn.paging = function(options){
/**
@param data {json} 所有的數據
@param numBtnOnePage {number} 顯示幾個帶頁數按鈕
@param numOnePage {number} 每頁顯示幾條數據
@param btnGroupLoc {selector} 帶頁數按鈕位置
@param tpl {selector} 視圖模板
@param tplParam {string} 視圖模板的參數對象
@param dataLoc {selector} 視圖顯示位置
*/
var defaults = {
numBtnOnePage : 5, /*默認5個翻頁按鈕*/
numOnePage : 7, /*默認顯示7條數據*/
};
var opts = $.extend(defaults, options);
opts.numBtnOnePage = Number(opts.numBtnOnePage);
opts.numOnePage = Number(opts.numOnePage);
var $this = $(this),
$firstPageBtn = $this.find(".pure-button.first"), /*首頁*/
$lastPageBtn = $this.find(".pure-button.last") , /*尾頁*/
$prevPageBtn = $this.find(".pure-button.prev") , /*上一頁*/
$nextPageBtn = $this.find(".pure-button.next") ; /*下一頁*/
if(opts.data){
var dataLength = opts.data.length,
pageCount = Math.ceil(dataLength/opts.numOnePage); //總頁數
// 爲產品專區添加顯示記錄和頁數
$this.find(".recordCount .num").text(dataLength);
$this.find(".pageCount .num").text(pageCount);
if(dataLength == 0){
$firstPageBtn.addClass("disabled");
$lastPageBtn.addClass("disabled");
$prevPageBtn.addClass("disabled");
$nextPageBtn.addClass("disabled");
$(opts.dataLoc).html("");
$(opts.btnGroupLoc).html("");
$firstPageBtn.attr({"data-page-index": ""});
$lastPageBtn.attr({"data-page-index": ""});
return 0;
}else {
$firstPageBtn.removeClass("disabled");
$lastPageBtn.removeClass("disabled");
$prevPageBtn.removeClass("disabled");
$nextPageBtn.removeClass("disabled");
$firstPageBtn.attr({"data-page-index": 1});
$lastPageBtn.attr({"data-page-index": pageCount});
}
}
/*
* 切割數據
* @param {number} group 第幾組數據
* @return {data} 截取之後的數據
*/
function sliceData(group){
var result = opts.data.slice(0+opts.numOnePage*(group-1), opts.numOnePage+opts.numOnePage*(group-1));
return result;
}
/**
* 創建翻頁按鈕,創建的新的翻頁視圖,視方向而定,選中第一個或者最後一個按鈕
* @param {number} n 爲第幾組翻頁按鈕
* @param {string} direction 翻頁方向
* @return {view} 返回一個視圖
*/
function pagingBtn(n, direction){
if(direction == "left"){
var lengthBtns = opts.numBtnOnePage;
for(var i = 0, itemList=""; i < lengthBtns; i++){
if(i == lengthBtns-1){
itemList = itemList + '<li><a class="pure-button pure-button-active nowPage" href="javascript:void(0)" data-page-index="'+Number(opts.numBtnOnePage*(n-1)+Number(i+1))+'">'+Number(opts.numBtnOnePage*(n-1)+(i+1))+'</a></li>';
}else{
itemList = itemList + '<li><a class="pure-button" href="javascript:void(0)" data-page-index="'+Number(opts.numBtnOnePage*(n-1)+(i+1))+'">'+Number(opts.numBtnOnePage*(n-1)+(i+1))+'</a></li>';
}
}
}
if(direction == "right"){
var remainPage = pageCount-opts.numBtnOnePage*(n-1);
var lengthBtns = (opts.numBtnOnePage<remainPage)? opts.numBtnOnePage : remainPage;
for(var i = 0, itemList = ""; i < lengthBtns; i++){
if(i == 0){
itemList = itemList + '<li><a class="pure-button pure-button-active nowPage" href="javascript:void(0)" data-page-index="'+Number(opts.numBtnOnePage*(n-1)+(i+1))+'">'+Number(opts.numBtnOnePage*(n-1)+(i+1))+'</a></li>';
}else{
itemList = itemList + '<li><a class="pure-button" href="javascript:void(0)" data-page-index="'+Number(opts.numBtnOnePage*(n-1)+(i+1))+'">'+Number(opts.numBtnOnePage*(n-1)+(i+1))+'</a></li>';
}
}
}
$(opts.btnGroupLoc).html(itemList);
}
/**
* [renderTpl description]
* @param {selector} tpl 模板的選擇器
* @param {json} pagedata 需要渲染的數據
* @return {view} 返回視圖
*/
function renderTpl(tpl, pagedata, dataLoc){
pagedata[opts.tplParam] = pagedata;
var source = $(tpl).html();
var template = Handlebars.compile(source);
$(dataLoc).html(template(pagedata));
}
function bindEvent(){
$this.off("click", ".pure-button").on("click", ".pure-button", function(){
var $thisPage = $(this);
if($thisPage.attr("data-page-index")!=undefined&&$thisPage.attr("data-page-index")!=""){
var thisPageIndex = $thisPage.attr("data-page-index");
var tempData = sliceData(thisPageIndex);
tempData[opts.tplParam] = tempData;
renderTpl(opts.tpl, tempData, opts.dataLoc);
$thisPage.addClass("pure-button-active nowPage")
.parent().siblings().find("a").removeClass("pure-button-active nowPage");
if($this.find("[data-page-index="+thisPageIndex+"]").length>1){
$this.find("[data-page-index="+thisPageIndex+"]").addClass("pure-button-active nowPage");
$this.find("[data-page-index!="+thisPageIndex+"]").removeClass("pure-button-active nowPage");
}else {
$firstPageBtn.removeClass("pure-button-active nowPage");
$lastPageBtn.removeClass("pure-button-active nowPage");
}
if(pageCount == 1){
$prevPageBtn.addClass("disabled");
$nextPageBtn.addClass("disabled");
}else {
if(thisPageIndex == 1) {
$prevPageBtn.addClass("disabled");
$nextPageBtn.removeClass("disabled");
}else if(thisPageIndex == pageCount){
$prevPageBtn.removeClass("disabled");
$nextPageBtn.addClass("disabled");
}else {
$prevPageBtn.removeClass("disabled");
$nextPageBtn.removeClass("disabled");
}
}
}
});
$this.off("click", ".pure-button.prev,.pure-button.next")
.on("click", ".pure-button.prev,.pure-button.next", function(){
var $pageSwitch = $(this);
if($pageSwitch.hasClass("disabled")){
return 0;
}else {
var currentPage = $(opts.btnGroupLoc).find(".pure-button-active.nowPage");
var currentPageIndex = currentPage.attr("data-page-index");
if($pageSwitch.hasClass("prev")){
var prevPageIndex = currentPageIndex - 1;
if(currentPageIndex%opts.numBtnOnePage == 1){
var nGroup = Math.floor(currentPageIndex/opts.numBtnOnePage);
pagingBtn(nGroup, "left");
renderTpl(opts.tpl, sliceData(prevPageIndex), opts.dataLoc);
$nextPageBtn.removeClass("disabled");
}else{
$this.find("[data-page-index="+currentPageIndex+"]").removeClass("pure-button-active nowPage");
$this.find("[data-page-index="+prevPageIndex+"]").addClass("pure-button-active nowPage");
renderTpl(opts.tpl, sliceData(prevPageIndex), opts.dataLoc);
$nextPageBtn.removeClass("disabled");
if(prevPageIndex == 1){
$prevPageBtn.addClass("disabled");
}
}
}else if($pageSwitch.hasClass("next")){
var nextPageIndex = Number(currentPageIndex) + 1;
if(currentPageIndex%opts.numBtnOnePage == 0){
var nGroup = Math.floor(Number(currentPageIndex/opts.numBtnOnePage)+1);
pagingBtn(nGroup, "right");
renderTpl(opts.tpl, sliceData(nextPageIndex), opts.dataLoc);
}else{
$this.find("[data-page-index="+currentPageIndex+"]").removeClass("pure-button-active nowPage");
$this.find("[data-page-index="+nextPageIndex+"]").addClass("pure-button-active nowPage");
renderTpl(opts.tpl, sliceData(nextPageIndex), opts.dataLoc);
$prevPageBtn.removeClass("disabled");
}
if(nextPageIndex == pageCount){
$nextPageBtn.addClass("disabled");
}
}
}
});
$this.off("click", ".pure-button.first,.pure-button.last")
.on("click", ".pure-button.first,.pure-button.last", function(){
var $pageBothEnd = $(this),
currentPage = $pageBothEnd.attr("data-page-index");
if(currentPage!=""){
if($pageBothEnd.hasClass("first")){
if($(opts.btnGroupLoc).filter("li:first").children("a").attr("data-page-index")==1){
return 0;
}else {
pagingBtn(1, "right");
$this.find("[data-page-index=1]").addClass("pure-button-active nowPage");
$this.find("[data-page-index!=1]").removeClass("pure-button-active nowPage");
$prevPageBtn.addClass("disabled");
}
}else if($pageBothEnd.hasClass("last")){
if($(opts.btnGroupLoc).find("li:last").children("a").attr("data-page-index")==pageCount){
return 0;
}else {
pagingBtn(Math.ceil(pageCount/opts.numBtnOnePage), "right");
$this.find("[data-page-index="+pageCount+"]").addClass("pure-button-active nowPage");
$this.find("[data-page-index!="+pageCount+"]").removeClass("pure-button-active nowPage");
$nextPageBtn.addClass("disabled");
}
}
}
});
}
/*函數執行入口*/
$firstPageBtn.removeClass("pure-button-active nowPage");
$lastPageBtn.removeClass("pure-button-active nowPage");
$prevPageBtn.removeClass("disabled");
$nextPageBtn.removeClass("disabled");
pagingBtn(1, "right");
$firstPageBtn.addClass("pure-button-active nowPage");
renderTpl(opts.tpl, sliceData(1), opts.dataLoc);
if(pageCount == 1){
$prevPageBtn.addClass("disabled");
$nextPageBtn.addClass("disabled");
$firstPageBtn.addClass("pure-button-active nowPage");
$lastPageBtn.addClass("pure-button-active nowPage");
bindEvent();
}else if(pageCount == 0){
$prevPageBtn.addClass("disabled");
$nextPageBtn.addClass("disabled");
$prevPageBtn.addClass("disabled");
$nextPageBtn.addClass("disabled");
}else{
$prevPageBtn.addClass("disabled");
bindEvent();
}
}
})(jQuery);
總結:根據設置的每頁顯示的條數和每頁要顯示的頁數,切割獲取來的data,繪製頁面和繪製新的按鈕組。
前端搜索也是對json進行操作,這個方法僅適用相關字段”secCode”和”secAbbr”。
function newsSelect(keyword, jsonData) {
if (keyword == "") {
return jsonData;
} else {
for (var i = 0; i < jsonData.length; {
if (jsonData[i].secCode.indexOf(keyword) > -1 || jsonData[i].secAbbr.indexOf(keyword) > -1) {
i++;
} else {
jsonData.splice(i, 1);
}
}
return jsonData;
}
}