闲话部分

最近闲着实在无聊,就做了点小东西练练手,由于原来一直在用AspNetPager进行分页,而且也进行了深度的定制与原有系统整合的也不错,不过毕竟是用别人的,想着看自己能试着做出来不能,后台的分页插件已经有比较成熟的了,那就自己试着写一个前台分页吧。

话不多说,先上效果图:

优点与缺点

来说说优缺点吧,首先AspNetPager是后台分页控件,所以在向客户端回传HTML文档之前生成HTML阶段 就会把分页代码生成完毕,然后回传,而JS是前端代码,就是HTML文档在服务器组织完毕往客户端传送完毕之后才登上舞台。基于上述的区别,很容易总结出下面的优缺点:

优点:

1,轻量级,引入JS即可,十分方便部署与使用。

2,与后台程序语言无关,可以在任何语言平台上使用。

3,减少服务器负担,减少传输成本,加快响应速度,改善用户体验。

4,前端代码没有被编译,方便维护和管理。

缺点:

1,不支持SEO优化。

2,需要单独编写接口。

基本思路

1,我们需要通过一些参数如:记录总条数(itemCount)、每页条数(pageSize)来计算总共可以分的页数(pageCount),itemCount需要通过请求数据来获取,而pageCoun则需要通过用户来指定。

2,我们需要知道当前是在第几页(currPage)。当页面首次加载的时候默认为1,用户也可以指定默认加载时处在第几页上。当翻页时就会获得一个新的currPage。

3,有了这些我们似乎是可以开始工作了,首页 尾页很好解决,首页页码永远为1,而尾页页码永远为pageCount,上一页 下一页也可以解决,上一页为 currPage-1 ,下一页为 currPage+1。似乎很完美,不过不要忘了,上一页页码为currPage-1只能是 在currPage>1的时候,而下一页页码为currPage+1则只能是在currPage<pageCount的时候,我想你一定知道为什么,所以在这里要判断一下。

4,通过currPage和pageSize,我们可以很轻松的计算出当前显示的记录为第几条~第几条,前面也获取到了pageCount,pageSize等数据,因此可以拼接字符串,来显示分页信息

信息显示例如:  共12条  第1/4页  第1~3条  3条/页

5,重头戏来了,对于中间页码部分的处理。简单处理的话很好办,从1到pageCount依次排列,似乎就可以了,但是不要忘了,假如你这个列表有几十页甚至上百页,那这样排列显然不够优雅,那么我们需要另外一个参数,那就是中间显示页码的个数(showPageCount),当页码很多的时候,最多只显示 2×showPageCount+1个页码。你一定会问,为什么是 2×showPageCount+1,而不是showPageCount。原因是我这里为了判断方便,showPageCount的含义为,当前页面左右两边出现的页码个数。

例如:总共有10页,当前页为5,showPageCount为2,

那么页码则显示为:  首页  上一页   3  4  5  6  7  下一页  尾页

意外情况:如果左边或者右边显示不够showPageCount的页码数量,为了保持页码显示量是一定的,则会从另外一侧补全。

例如:总共10也,当前页面为2,showPageCount为4,左侧只有1个页面可以显示,则从右侧补全,

页码显示为:  首页  上一页   1    3  4  5  6  7  8  9  下一页   尾页

6,再在最后设置一个 Input 和 A 标签用作转到指定页面功能。

7,到此为止,我们只需要把上面的各个步骤 分别拼接字符串 输出到页面上就OK了,但是,还有一个重要话题没有讨论,目前为止,我们只是实现了分页的结构,但是功能似乎还没有实现。实现功能有两种方式:

(1),给页码标签的 href 属性绑定对应的链接,后面跟参数如 href="Article.aspx?page=2" 点击之后带上页码参数2 去请求第二页的信息。我们在后台程序通过Request到page的值,给Repeater控件做相应的绑定也好,输出字符串也好,都可以实现功能。

(2),添加 onclick 属性,并绑定函数,通过函数做 ajax 请求,通过响应的函数(可以是键值对,也可以是HTML字符串),来给替换当前页面上的列表,产生新的列表,同时分页的当前页也需要更换成对应的当前页,完成之后效果实现。

第一种很简单,在拼接字符串的时候,顺带这把 href  属性写了就完事,这里不做过多叙述,关键说第二种,由于采用了ajax 在翻页的时候做请求,拿到响应数据,改写列表容器,既然如此,那么我们页面首次加载获取pageCount的时候,也可以顺便把列表给绑定了。简单总结起来大致流程如下:

A:页面加载——收集请求参数和查询条件(currPage为1),ajax请求,拿到响应信息(至少包括 itemCount 和 列表信息),通过回调函数,用itemCount 计算分页的各项参数 生成分页,通过列表信息,生成列表,完成初次加载。

B:翻页事件——再次收集求情和查询条件(currPage为当前页码),ajax请求,拿到响应信息(至少包括 itemCount 和 列表信息),通过回调函数,用itemCount 计算分页的各项参数 拼接字符串改写分页容器内容,通过列表信息,改写列表容器内容,完成初次加载。

我们可以直观的发现,A事件和B事件,流程基本一致,唯一的区别就是 currPage的值不同,因此我们可以做一个类似于递归的方法(不算严格意义上的递归),我们写一个 Load() 函数来用作 列表和分页的首次加载,在容器值被改写过之后,需要给 页码的 onclick 事件绑定函数,此时我们绑用本身这个Load()函数,所以每次点击后仍然绑定的是Load()方法。这样一段代码,就可以在两个事件中重复使用了。

8,关于传参,刚才我们一直提到 手机请求参数和查询条件,例如:容器ID,列表所属分类ID,每页条数,URL格式等等。 那么我们究竟如何把参数传递到方法中去?想实现目的,以下几种方式都可以。

A:声明全局变量,在函数中调用,但是这种方式会造成大量的变量冗余,同时 Load()函数需要 传入大量的参数,如:Load(agrA,agrB , agrC , agrD , agrE , agrF ... ),不可取。

B : 传入Json字符串,通过键值对的方式传入参数,这种方法,虽说只有一个参数,但是在编写的时候过于繁琐,而且无法指定默认值,或者可选项,需要在JS中重新判断,不可取。

C : 如果说上面两个都PASS掉了,那么你一定知道接下来要做什么了,没错!JavaScript是一门面向对象的语言,虽然经常被人们忽略,但是他是可以使用对象和面向对象的一些编程方式的,因此我们可以建立分页的实体类,然后每次调用的时候,new() 出来一个新的对象,这样既可以保证同一个页面有多个分页的时候互不冲突,同时又可以优雅地指定我们的属性值,还可以通过类似于构造函数的方式进行默认值的初始化。

调用方式

引入jquery、ruguoPager和css:

 <script src="js/jquery-1.11.1.min.js"></script>
<script src="js/ruguoPager-1.0.js"></script>
<link rel="stylesheet" href="css/ruguoPager.css">

编写html结构指定好ID:

<div class="ctn">
  <div class="news" name="pager1">
    <ul class="list" id="news_ul"></ul>
    <div class="box_height_1000px"></div>
    <div class="ruguoPager_red" id="pager1"></div>
  </div>
</div>

在HTML页面上加入script标签 指定对象参数 进行分页

 <script>
  var pager = new ruguoPager();
  pager.pagerType="ajax";
  pager.objName="pager";
  pager.pagerID="pager1";
  pager.listID="news_ul";
7   pager.toPoint="pager1"
8   pager.showPageSize=;
  pager.pageSize=;
  pager.currPage=;
  pager.typeID=;
  pager.pagerUrl="news/list_{ruguo:pageNum}.html";
  pager.itemStr="<li><a href='news/detail_{ruguo:id}.html'>{ruguo:title}</a>[{ruguo:datetime}]</li>";
  pager.ajaxUrl="ajax/getArticleList.ashx";
  ruguoPagerLoad(pager);
</script>

参数列表(参数名,参数含义,可选值,必须)

 pagerType  初始化类型 'ajax'  or  ' url'   
 objName  对象名  string  *
 pagerID  分页容器ID  string  *
 listID  列表容器ID  string  -
 currPage  当前页  int  
 pageSize  每页条数  int  
 itemCount  记录总条数  int  
 showPageSize  显示页码数  string  
 pagerUrl  分页路径格式  string  -
 typeID  列表类别ID  int  
 titLen  列表标题字数  int  
 itemStr  列表标题格式  string  
 ajaxUrl  ajax请求地址  string  *
 toPoint  锚点标记  string  
 isShowFirst  是否显示首页按钮  'always'  ,  'auto'  ,  'none'  
 isShowPreviousPage  是否显示上一页按钮  'always'  ,  'auto'  ,  'none'  
 isShowNextPage  是否显示下一页按钮  'always'  ,  'auto'  ,  'none'  
 isShowLastPage  是否显示尾页按钮  'always'  ,  'auto'  ,  'none'  
 isShowPages  是否显示页码按钮  'always'  ,  'auto_0'  ,  'auto_1'  ,  'none'  
 isShowGo  是否显示跳转  'always'  ,  'auto'  ,  'none'  

总结

在编写插件的过程中,遇到了很多实际的问题,并一个一个的加以解决,得到了不少心得,在这里总结一下。

1,类的使用

在写Javascript的时候,尤其是在Jquery被广泛使用知乎,我们往往会在页面中罗列一个接一个的函数, 但是有时候我们尝试着使用一下类,会使得代码变得更加优雅。在写这个插件之前,只知道JS可以写类,实例化对象,但是究竟怎么用,却从来没试过,甚至怎么定义一个类都不知道。通过本例,初步了解了JS中类的基本使用方式。

2,函数的重载

在解决 Load() 函数重用问题上,我想使用重载,但是根据自己的猜想,试了一下没有成功,经过查资料发现正确的使用方式。在C#中我们知道,方法可以重载,要求方法名相同,返回类型或者形参类型、数量不同。然而针对于JS来说,是没有重载一说的,因为JS是若类型语言,在调用方法的时候,根本没有参数类型以及返回类型一说。虽然如此,好在参数个数还是可以检测到的,所以根据这一特点,可以进行模拟重载,但是注意并非真正重载。

3,全局变量

在写插件时候,第一次实例化的对象,并把对象的各个属性通过AJAX传递,拿到了响应信息,完成了分页和列表的首次加载。当点击分页时候,需要再次执行同样的操作,因此需要再次进行实例化对象,这样一来方法就无法复用,意味着,页面上每多一个分页,就需要copy一份js用作不同的 在点击分页时候的实例化。所以我就在想,点击分页事件时候的对象,与第一次的对象不一样的仅仅只是当前页码而已,所以通过对象本身包含对象名的方式,在绑定分页事件方法时,把对象名当作参数放在了Load()方法中,并多了一个当前页参数,通过模拟重载 顺利完成Load()方法的复用。虽然JS没有非常严格的访问级别,但是我想写在文档流中的变量应该都是全局变量,在初次实例化时候的对象同样也是,所以绑定分页事件方法中的参数 应该是可以调用到 全局对象的,结果证明我的猜想完全正确。

4,ajax分页用户体验

通过ajax分页时候会有一个问题,那就是点击分页之后,由于页面并不刷新或者跳转,而是直接修改了页面容器的内容,所以页面会保持在列表最下方不动,每次点击完分页,需要手动把网页拨回到最顶部,然后再慢慢往下翻着看,很麻烦,所以我做了一个本地描点,在初次实例化的时候需要传锚点ID,点击之后,返回到锚点处。
效果类似于腾讯新闻列表的效果:http://news.qq.com/top_index.shtml

5,jquery绑定事件传参

在写插件过程中,起初用到了需要往jquery绑定事件中传参,由于习惯了使用 例如 $("a").click(function(){ alert("hello world"); });这样的绑定方式,所以如何往click事件所执行的方法中传入参数一时间十分苦恼,后来经过查询,知道了可以使用 这样的方式进行传参:$("a").bind("click",{myValue:hello world},function(event){ alert(event.data.myValue) }); ,虽然后来有了更好的方式,无需传参了,但是也算是一个不小的收获吧。

6,当json遇上HTML

json是我们网上常用的传递数据的格式,而且js可以很轻松的解析,但是由于json遇到html中的 尖括号(< >)会出现问题,无法正确返回,因此,我们需要响应数据的时候进行HTML编码,在回调函数中,对拿到的编码后的字符串进行反编码。另外顺带提一下,在使用eval()解析数据的时候最好里面再套上一个"("+data+")",原因是json中的大括号会影响js的结构。

存在的问题

1,代码重用部分,其实并没有把url与ajax的方式完全区分开,由于当使用url的时候,初次加载列表和 总页数 可以通过后台绑定出来,因此在点击分页的时候,就无需再次请求数据,仅仅进行前台的计算即可,可以减少一次请求。

2,代码写的比较乱,大伙凑合着看吧。

3,本人才疏学浅,写代码纯属业余兴趣爱好,还望跟各位大神多多学习,存在的问题或者是更好的解决方案,还请不吝赐教,帮助我完善插件,网上成熟的插件有很多,本人献丑不敢说分享劳动成果工,只能说在学习中遇到的问题拿来给暂时还没有遇到的人,少走一些弯路,同时满足一下自己小小的成就感,仅此而已。

代码与文章都是博主辛苦一点一点码出来的,请尊重博主辛勤劳动,欢迎转载,转载请注明出处,更多交流请关注 D调码农的笔记簿 http://www.cnblogs.com/webconfig

最后放出下载地址

相关文档下载:http://files.cnblogs.com/webconfig/ruguoPager.rar

自制Javascript分页插件,支持AJAX加载和URL带参跳转两种初始化方式,可用于同一页面的多个分页和不同页面的调用的更多相关文章

  1. 转载:Flash AS3.0 加载外部资源(图片,MP3,SWF)的两种方式

    Flash AS3.0 加载外部资源(图片,MP3,SWF)的两种方式 出自:http://www.cnblogs.com/top5/archive/2012/08/04/2623464.html 关 ...

  2. Jquery前端分页插件pagination同步加载和异步加载

    上一篇文章介绍了Jquery前端分页插件pagination的基本使用方法和使用案例,大致原理就是一次性加载所有的数据再分页.https://www.jianshu.com/p/a1b8b1db025 ...

  3. mybatis分页插件以及懒加载

    1.   延迟加载 延迟加载的意义在于,虽然是关联查询,但不是及时将关联的数据查询出来,而且在需要的时候进行查询. 开启延迟加载: <setting name="lazyLoading ...

  4. jQuery Mobile 手动显示ajax加载器,提示加载中...

    在使用jQuery Mobile开发时,有时候我们需要在请求ajax期间,显示加载提示框(例如:一个旋转图片+一个提示:加载中...).这个时候,我们可以手动显示jQuery Mobile的加载器,大 ...

  5. 支持无限加载的js图片画廊插件

    natural-gallery-js是一款支持无限加载的js图片画廊插件.该js图片画廊支持图片的懒加载,可以对图片进行搜索,分类,还可以以轮播图的方式来展示和切换图片. 使用方法 在页面中引入下面的 ...

  6. phpcms列表分页ajax加载更多

    1.在phpcms\modules\content\index.php文件中添加以下函数: /*列表分页ajax加载更多*/ public function homeajaxlist() {  if( ...

  7. jQuery EasyUI动态添加控件或者ajax加载页面后不能自动渲染问题的解决方法

    博客分类: jquery-easyui jQueryAjax框架HTML  现象: AJAX返回的html无法做到自动渲染为EasyUI的样式.比如:class="easyui-layout ...

  8. 【转】js JavaScript 的性能优化:加载和执行

    JavaScript 的性能优化:加载和执行 转自:https://www.ibm.com/developerworks/cn/web/1308_caiys_jsload/ 随着 Web2.0 技术的 ...

  9. JavaScript如何实现上拉加载,下拉刷新?

    转载地址: 面试官:JavaScript如何实现上拉加载,下拉刷新? 一.前言 下拉刷新和上拉加载这两种交互方式通常出现在移动端中 本质上等同于PC网页中的分页,只是交互形式不同 开源社区也有很多优秀 ...

随机推荐

  1. Bootstrap_排版_文字样式

    一.段落 段落是排版中另一个重要元素之一.在Bootstrap中为文本设置了一个全局的文本样式(这里所说的文本是指正文文本): 1.全局文本字号为14px(font-size). 2.行高为1.428 ...

  2. Python自动化运维之18、Python操作 MySQL、pymysql、SQLAchemy

    一.MySQL 1.概述 什么是数据库 ? 答:数据的仓库,和Excel表中的行和列是差不多的,只是有各种约束和不同数据类型的表格 什么是 MySQL.Oracle.SQLite.Access.MS ...

  3. sql server 2008 case when

    CASE WHEN的两种格式 1.简单Case函数 CASE sex WHEN '1' THEN '男' WHEN '2' THEN '女' ELSE '其他' END 2.Case搜索函数 CASE ...

  4. android 多线程断点续传下载

    今天跟大家一起分享下Android开发中比较难的一个环节,可能很多人看到这个标题就会感觉头很大,的确如果没有良好的编码能力和逻辑思维,这块是很难搞明白的,前面2次总结中已经为大家分享过有关技术的一些基 ...

  5. @action 注解

    ================================================= 下载 注解配置 private String fileName; private String co ...

  6. Filter plugins ? mutate:

    filter { grok { match => [ "message" , "\s*%{IPORHOST:clientip}\s+\-\s+\-\s+\[%{HT ...

  7. 【HDOJ】2195 Monotone SE Min

    简单DP.将[0,1]的浮点数离散化为[0,1000]的整数.最后再除以1000^2. /* 2195 */ #include <cstdio> #include <cstring& ...

  8. 【HDOJ】1208 Pascal's Travels

    记忆化搜索.注意当除右下角0外,其余搜索到0则返回. #include <algorithm> #include <cstdio> #include <cstring&g ...

  9. Facebook 开源 AI 所使用的硬件平台 'Big Sur'

    Facebook 开源 AI 所使用的硬件平台 'Big Sur' Facebook 今开源其 AI 所使用的硬件平台 'Big Sur'.'Big Sur' 是兼容开放机架的 GPU 加速硬件平台. ...

  10. !!!全球最流行开源硬件平台!不知道就OUT了!

    全球最流行的几个开源硬件平台!不知道就OUT了! 随着物联网的推广和普及,五年内全球会有200亿台智能设备的需求,而如今随着创客概念的兴起,开源硬件也越加的火热,让我们来看看现在都有哪些主流的开源硬件 ...