当前位置: 首页 > news >正文

实现滑动分页(微博分页方式)

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

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

  页面代码Default.aspx:

<head runat="server">
    <title>滑动分页</title>
    <style type="text/css">
        #divPaging{width:500px;margin:0 auto;text-align:right;display:none}
        #divLoading,#divReLoading{width:500px;margin:0 auto;text-align:center;display:none}
        #divReLoading a{text-decoration:none}
        #divReLoading a:hover{text-decoration:underline}
    </style>
</head>
<body>
    <form id="form1" runat="server">
        <div style="border:solid 1px #888;width:500px;margin:0 auto" runat="server" id="div" enableviewstate="false">
        </div>
        <div id="divPaging">跳转到第<asp:DropDownList runat="server" ID="ddl" AutoPostBack="true" OnSelectedIndexChanged="ddl_OnSelectedIndexChanged"></asp:DropDownList>页</div>
        <div id="divLoading">正在加载......</div>
        <div id="divReLoading">加载失败,<a href="javascript:Reload()">重新加载</a>页面</div>
    </form>
</body>
</html>
Javascript代码:
function $(id) { return document.getElementById(id); }
    var ajax = new AjaxHasPool();
    var method = "get";
    var url = "Handler.ashx?";
    indexOfPage = 1;
    isLoading = false;
    function WhenScroll() {
        if (document.documentElement.scrollTop + document.documentElement.clientHeight > document.documentElement.scrollHeight - 10 && indexOfPage <= 2 && !isLoading) {
            $("divLoading").style.display = "block";
            isLoading = true;
            var pageIndex = $("<%=ddl.ClientID %>").options[$("<%=ddl.ClientID %>").selectedIndex].value;
            ajax.Startup(null, url + "pageIndex=" + pageIndex + "&indexOfPage=" + indexOfPage, method, EP);
        }
    }

    function Reload() {
        if (indexOfPage <= 2 && !isLoading) {
            $("divLoading").style.display = "block";
            $("divReLoading").style.display = "none";
            isLoading = true;
            var pageIndex = $("<%=ddl.ClientID %>").options[$("<%=ddl.ClientID %>").selectedIndex].value;
            ajax.Startup(null, url + "pageIndex=" + pageIndex + "&indexOfPage=" + indexOfPage, method, EP);
        }
    }

    function EP(xmlObj) {
        $("divLoading").style.display = "none";
        if (xmlObj.responseText == "false") {
            $("divReLoading").style.display = "block";
        }
        else {
            if (indexOfPage == 2) {
                $("divPaging").style.display = "block";
            }
            else {
                $("divPaging").style.display = "none";
            }

            $("div").innerHTML += xmlObj.responseText;
            ++indexOfPage;
        }
        isLoading = false;
    }

    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

public partial class _Default : System.Web.UI.Page 
{
    private XMLManager manager = null;
    private PagedDataSource pds = null;

    protected void Page_Load(object sender, EventArgs e)
    {
        
        manager = new XMLManager();
        pds = new PagedDataSource();
        pds.DataSource = manager.GetData(0, 0);
        pds.AllowPaging = true;
        pds.PageSize = 30;
        if (!IsPostBack)
        {
            for (int i = 0; i < pds.PageCount; ++i)
            {
                this.ddl.Items.Add(new ListItem(Convert.ToString(i + 1), Convert.ToString(i)));
            }
            this.ddl.SelectedIndex = 0;
            pds.CurrentPageIndex = 0;
            List<obj> list = manager.GetData(pds.FirstIndexInPage, 10);
            StringBuilder sb = new StringBuilder();
            foreach (obj item in list)
            {
                sb.Append("<div style='height:100px;border-bottom:dotted 1px #322323'>");
                sb.Append(item.Content);
                sb.Append(" ");
                sb.Append(item.User);
                sb.Append("</div>");
            }
            div.InnerHtml = sb.ToString();
        }
    }

    protected void ddl_OnSelectedIndexChanged(object sender, EventArgs e)
    {
        this.pds.CurrentPageIndex = this.ddl.SelectedIndex;
        List<obj> list = manager.GetData(this.pds.FirstIndexInPage, 10);
        StringBuilder sb = new StringBuilder();
        foreach (obj item in list)
        {
            sb.Append("<div style='height:100px;border-bottom:dotted 1px #322323'>");
            sb.Append(item.Content);
            sb.Append(" ");
            sb.Append(item.User);
            sb.Append("</div>");
        }
        this.div.InnerHtml = sb.ToString();
    }

}

说明:

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

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

 

ajax异步请求处理类Handler.ashx

public class Handler : IHttpHandler {

    XMLManager manager = new XMLManager();
    
    public void ProcessRequest (HttpContext context) {
        context.Response.ContentType = "text/plain";
        int pageIndex;
        bool hasPageIndex = Int32.TryParse(context.Request.QueryString["pageIndex"], out pageIndex);
        int indexOfPage;
        bool hasIndexOfPage = Int32.TryParse(context.Request.QueryString["indexOfPage"], out indexOfPage);
        StringBuilder sb = new StringBuilder(200);
        if (hasIndexOfPage && hasPageIndex)
        {
            PagedDataSource pds = new PagedDataSource();
            XMLManager manager = new XMLManager();
            pds.DataSource = manager.GetData(0, 0);
            pds.CurrentPageIndex = pageIndex;
            pds.PageSize = 30;
            pds.AllowPaging = true;
            int firstIndexOfPage = pds.FirstIndexInPage;
            List<obj> list = manager.GetData(firstIndexOfPage + (10 * indexOfPage), 10);
            foreach (obj item in list)
            {
                sb.Append("<div style='height:100px;border-bottom:dotted 1px #322323'>");
                sb.Append(item.Content);
                sb.Append(" ");
                sb.Append(item.User);
                sb.Append("</div>");
            }
        }
        else
            sb.Append("false");
        context.Response.Write(sb.ToString());
    }
 
    public bool IsReusable {
        get {
            return false;
        }
    }

}

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

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

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

 

相关文章:

  • MySQL 读写分离介绍及搭建
  • corosync + pacemaker + nfs 构建高可用mysql集群
  • GCC编译器使用
  • EHcache经典配置
  • 基于 lua-resty-upload 实现简单的文件上传服务
  • 面试题系列一之 程序生命周期
  • Linux常用网络命令
  • 静态long类型常量serialVersionUID的作用
  • 用百度输入法的用户体验
  • 代码写累了就画点注释陶冶情操
  • 深入解析Java中的装箱和拆箱
  • SQL SERVER 表最小行的一个纠结问题
  • 利用Android Lost通过互联网或短信远程控制安卓设备
  • http://blog.csdn.net/huang_xw/article/details/7090173
  • Outlook 2013 在邮件里面点击超链接时弹出“组织策略阻止我们为您完成此操作”...
  • IE9 : DOM Exception: INVALID_CHARACTER_ERR (5)
  • JS 中的深拷贝与浅拷贝
  • 【腾讯Bugly干货分享】从0到1打造直播 App
  • Android 控件背景颜色处理
  • JavaScript 无符号位移运算符 三个大于号 的使用方法
  • JS笔记四:作用域、变量(函数)提升
  • Linux编程学习笔记 | Linux IO学习[1] - 文件IO
  • Promise初体验
  • Vue.js 移动端适配之 vw 解决方案
  • vuex 笔记整理
  • Web Storage相关
  • windows下如何用phpstorm同步测试服务器
  • 每个JavaScript开发人员应阅读的书【1】 - JavaScript: The Good Parts
  • 浅谈web中前端模板引擎的使用
  • 强力优化Rancher k8s中国区的使用体验
  • 我从编程教室毕业
  • PostgreSQL 快速给指定表每个字段创建索引 - 1
  • 阿里云服务器如何修改远程端口?
  • 数据可视化之下发图实践
  • ​​快速排序(四)——挖坑法,前后指针法与非递归
  • ​Kaggle X光肺炎检测比赛第二名方案解析 | CVPR 2020 Workshop
  • ​Linux Ubuntu环境下使用docker构建spark运行环境(超级详细)
  • #NOIP 2014#Day.2 T3 解方程
  • (C语言)求出1,2,5三个数不同个数组合为100的组合个数
  • (delphi11最新学习资料) Object Pascal 学习笔记---第2章第五节(日期和时间)
  • (Redis使用系列) SpirngBoot中关于Redis的值的各种方式的存储与取出 三
  • (Redis使用系列) Springboot 在redis中使用BloomFilter布隆过滤器机制 六
  • (Spark3.2.0)Spark SQL 初探: 使用大数据分析2000万KF数据
  • (附源码)spring boot火车票售卖系统 毕业设计 211004
  • (附源码)SSM环卫人员管理平台 计算机毕设36412
  • (官网安装) 基于CentOS 7安装MangoDB和MangoDB Shell
  • (十八)devops持续集成开发——使用docker安装部署jenkins流水线服务
  • (四)图像的%2线性拉伸
  • (算法)N皇后问题
  • (转) Face-Resources
  • .NET 4.0中的泛型协变和反变
  • .Net CF下精确的计时器
  • .NET 程序如何获取图片的宽高(框架自带多种方法的不同性能)
  • .net的socket示例
  • .NET构架之我见