zoukankan      html  css  js  c++  java
  • 实现滑动分页(微博分页方式)

      现在大家都在上微博,而微博的滑动分页引起了我的兴趣,于是自己模仿着做,以下是这段时间的成果(单纯实现,没有考虑到效率和其他细节问题)

      实现内容:以30条记录为一页,每页分三次显示,每当把滚动条拖动到离浏览器底部10px时就显示该页的其余部分,当该页数据全部显示完时就显示页码控件供用户跳转到其他页面。如果数据加载失败,显示重新加载连接,实现用户手动重新加载数据。

      页面代码Default.aspx:

     1 <head runat="server">
    2 <title>滑动分页</title>
    3 <style type="text/css">
    4 #divPaging{500px;margin:0 auto;text-align:right;display:none}
    5 #divLoading,#divReLoading{500px;margin:0 auto;text-align:center;display:none}
    6 #divReLoading a{text-decoration:none}
    7 #divReLoading a:hover{text-decoration:underline}
    8 </style>
    9 </head>
    10 <body>
    11 <form id="form1" runat="server">
    12 <div style="border:solid 1px #888;500px;margin:0 auto" runat="server" id="div" enableviewstate="false">
    13 </div>
    14 <div id="divPaging">跳转到第<asp:DropDownList runat="server" ID="ddl" AutoPostBack="true" OnSelectedIndexChanged="ddl_OnSelectedIndexChanged"></asp:DropDownList>页</div>
    15 <div id="divLoading">正在加载......</div>
    16 <div id="divReLoading">加载失败,<a href="javascript:Reload()">重新加载</a>页面</div>
    17 </form>
    18 </body>
    19 </html>

    Javascript代码:

     1 function $(id) { return document.getElementById(id); }
    2 var ajax = new AjaxHasPool();
    3 var method = "get";
    4 var url = "Handler.ashx?";
    5 indexOfPage = 1;
    6 isLoading = false;
    7 function WhenScroll() {
    8 if (document.documentElement.scrollTop + document.documentElement.clientHeight > document.documentElement.scrollHeight - 10 && indexOfPage <= 2 && !isLoading) {
    9 $("divLoading").style.display = "block";
    10 isLoading = true;
    11 var pageIndex = $("<%=ddl.ClientID %>").options[$("<%=ddl.ClientID %>").selectedIndex].value;
    12 ajax.Startup(null, url + "pageIndex=" + pageIndex + "&indexOfPage=" + indexOfPage, method, EP);
    13 }
    14 }
    15
    16 function Reload() {
    17 if (indexOfPage <= 2 && !isLoading) {
    18 $("divLoading").style.display = "block";
    19 $("divReLoading").style.display = "none";
    20 isLoading = true;
    21 var pageIndex = $("<%=ddl.ClientID %>").options[$("<%=ddl.ClientID %>").selectedIndex].value;
    22 ajax.Startup(null, url + "pageIndex=" + pageIndex + "&indexOfPage=" + indexOfPage, method, EP);
    23 }
    24 }
    25
    26 function EP(xmlObj) {
    27 $("divLoading").style.display = "none";
    28 if (xmlObj.responseText == "false") {
    29 $("divReLoading").style.display = "block";
    30 }
    31 else {
    32 if (indexOfPage == 2) {
    33 $("divPaging").style.display = "block";
    34 }
    35 else {
    36 $("divPaging").style.display = "none";
    37 }
    38
    39 $("div").innerHTML += xmlObj.responseText;
    40 ++indexOfPage;
    41 }
    42 isLoading = false;
    43 }
    44
    45 document.documentElement.onscroll = WhenScroll;

    说明:

      1.首先要实现监听拖动滚动条事件,那么就要订阅document.documentElement对象的onscroll事件。

          2.这里我实现的是当滚动条离达浏览器底部10px时就读取该页的其余部分,使用onscroll处理函数中的document.documentElement.scrollTop + document.documentElement.clientHeight > document.documentElement.scrollHeight - 10进行判断。document.documentElement.scrollTop表示浏览器垂直方向被卷去的长度,document.documentElement.clientHeight表示浏览器可视工作区的高度(区别于document.body.clientHeight表示内容高度,可能小于等于大于浏览器可视工作区的高度),document.documentElement.scrollHeight表示内容高度。

         3.indexOfPage用于说明请求的是当前页的第几部分数据,因只分3个部分,所以如果indexOfPage>2就表明当前页的数据已经加载完成了,无需加载。当然也可加载完全部数据后把document.documentElement.onscroll设为null,这样就一了百了了。

         4.isLoading用于确保数据加载的顺序,当一个加载未完成时不允许发起下一个加载请求。(这个要注意哦!!)

         5.这里的AjaxHasPool()是自己对ajax封装的函数,使用了简单的对象池,请求并发时效率有所提升(最近还没能抽出时间学jquery等框架,自己写一个勉强用着吧。。。)

    后台代码Default.aspx.cs

     1 public partial class _Default : System.Web.UI.Page 
    2 {
    3 private XMLManager manager = null;
    4 private PagedDataSource pds = null;
    5
    6 protected void Page_Load(object sender, EventArgs e)
    7 {
    8
    9 manager = new XMLManager();
    10 pds = new PagedDataSource();
    11 pds.DataSource = manager.GetData(0, 0);
    12 pds.AllowPaging = true;
    13 pds.PageSize = 30;
    14 if (!IsPostBack)
    15 {
    16 for (int i = 0; i < pds.PageCount; ++i)
    17 {
    18 this.ddl.Items.Add(new ListItem(Convert.ToString(i + 1), Convert.ToString(i)));
    19 }
    20 this.ddl.SelectedIndex = 0;
    21 pds.CurrentPageIndex = 0;
    22 List<obj> list = manager.GetData(pds.FirstIndexInPage, 10);
    23 StringBuilder sb = new StringBuilder();
    24 foreach (obj item in list)
    25 {
    26 sb.Append("<div style='height:100px;border-bottom:dotted 1px #322323'>");
    27 sb.Append(item.Content);
    28 sb.Append("&emsp;");
    29 sb.Append(item.User);
    30 sb.Append("</div>");
    31 }
    32 div.InnerHtml = sb.ToString();
    33 }
    34 }
    35
    36 protected void ddl_OnSelectedIndexChanged(object sender, EventArgs e)
    37 {
    38 this.pds.CurrentPageIndex = this.ddl.SelectedIndex;
    39 List<obj> list = manager.GetData(this.pds.FirstIndexInPage, 10);
    40 StringBuilder sb = new StringBuilder();
    41 foreach (obj item in list)
    42 {
    43 sb.Append("<div style='height:100px;border-bottom:dotted 1px #322323'>");
    44 sb.Append(item.Content);
    45 sb.Append("&emsp;");
    46 sb.Append(item.User);
    47 sb.Append("</div>");
    48 }
    49 this.div.InnerHtml = sb.ToString();
    50 }
    51
    52 }

    说明:

      1.这里的数据源是xml文件,写了个XmlManager类来操作,代码就不贴上来了。
      2.分页用System.Web.UI.WebControl下的PagedDataSource十分省心,但本次实现没有考虑效率问题所以出现重复操作xml文件的情况,实际项目中应避免哦!注意:用PagedDataSource进行分页要把其属性AllowPaging设为true,不然得不到分页效果。

      3.dropdownlist的选择更改事件是整个页面唯一一个使用非ajax实现的,目的是丢弃之前页面的全部,重新加载一个画面。这点对于我来说教训很大,之前刚学ajax时打算把网站的方方面面都异步处理,结果出现滥用的情况,是页面的javascript代码十分庞大,最后到测试期出现严重的显示问题并且无法找问题根源,这里也包括我对代码的管理等的问题。分清楚哪些地方需要使用ajax请求,那些地方刷新整个页面是十分重要的!!

    ajax异步请求处理类Handler.ashx

     1 public class Handler : IHttpHandler {
    2
    3 XMLManager manager = new XMLManager();
    4
    5 public void ProcessRequest (HttpContext context) {
    6 context.Response.ContentType = "text/plain";
    7 int pageIndex;
    8 bool hasPageIndex = Int32.TryParse(context.Request.QueryString["pageIndex"], out pageIndex);
    9 int indexOfPage;
    10 bool hasIndexOfPage = Int32.TryParse(context.Request.QueryString["indexOfPage"], out indexOfPage);
    11 StringBuilder sb = new StringBuilder(200);
    12 if (hasIndexOfPage && hasPageIndex)
    13 {
    14 PagedDataSource pds = new PagedDataSource();
    15 XMLManager manager = new XMLManager();
    16 pds.DataSource = manager.GetData(0, 0);
    17 pds.CurrentPageIndex = pageIndex;
    18 pds.PageSize = 30;
    19 pds.AllowPaging = true;
    20 int firstIndexOfPage = pds.FirstIndexInPage;
    21 List<obj> list = manager.GetData(firstIndexOfPage + (10 * indexOfPage), 10);
    22 foreach (obj item in list)
    23 {
    24 sb.Append("<div style='height:100px;border-bottom:dotted 1px #322323'>");
    25 sb.Append(item.Content);
    26 sb.Append("&emsp;");
    27 sb.Append(item.User);
    28 sb.Append("</div>");
    29 }
    30 }
    31 else
    32 sb.Append("false");
    33 context.Response.Write(sb.ToString());
    34 }
    35
    36 public bool IsReusable {
    37 get {
    38 return false;
    39 }
    40 }
    41
    42 }

    这里就是根据页码和页内索引获取数据,但有其他地方想分享一下:

      1.StringBuilder初始化时可以设定初始容量,这个初始容量对性能有一定的影响,加入输入的内容超过了这个容量,那么stringbuilder对象会扩容为原来容量的1两倍,而扩容会消耗一定的资源,所以设定一个大概的初始容量有利于性能的提高。

      2.一般讲string转化为int32、int64等数值类型时,我都会使用Int32.TryParse方法,就算转化失败都不会抛异常而是返回false,然后再进行具体的if else处理,要知道抛异常是耗资源的。

    如有更好的实现方法和改进的方式,请大家指教^_^

    欢迎添加我的公众号一起深入探讨技术手艺人的那些事!

    如果您觉得本文的内容有趣就扫一下吧!捐赠互勉!
      

  • 相关阅读:
    MFC中CDialog与其对话框资源的绑定 dll中资源的切换
    DirectDraw 显示 YUV
    ClipCursor与GetClipCursor 用法
    MFC消息处理流程概述 .
    HTML5 WebSocket 技术介绍
    NodepartySZ1 深圳聚会活动回顾总结[2012.01.08] CNode
    index QuickWeb文档
    Node.js Manual
    An innovative way to replace AJAX and JSONP using node.js and socket.io
    RequireJS
  • 原文地址:https://www.cnblogs.com/fsjohnhuang/p/2264045.html
Copyright © 2011-2022 走看看