Asp.net使用JQuery实现评论的无刷新分页及分段延迟加载效果
首先建立数据库,数据关系图如下:
本文要实现的效果就是在评论别人文章时,如果文章内容过长或者评论内容过长,实现的一个评论分段延迟加载的效果,即每页可显示30条评论,可每隔10条延迟加载一次以提高网页传输显示效率。
我所实现的页面延迟的原理如下图,就是求出X的距离小于100时进行加载延迟的评论,然后又设置了一个标记位,用来判断延迟加载了多少次,每页仅能加载30条评论记录。
然后再评论末端加载上页码实现无刷新进行分页的效果。
分页的方法也是比较简单的,这里自己实现了一个存储过程,使用到row_number()函数:
ALTER PROCEDURE ps_getpageandload @aid int, @startindex int, @endindex int AS select * from ( select Row_Number() over(order by CID) as rownum,Username,Comment from T_Comments where AID=@aid ) as T where T.rownum>=@startindex and T.rownum<=@endindex RETURN
就是输入一个起始位置的参数和结束位置的参数,取出中间的数据。
这样,在程序中就好取出数据了,比如:我第一页就是要1-30的数据,就让startindex=1,endindex=30就行了;第二页就是31-60的数据,同理。
LoadArticle.ashx:一个一般处理程序,用来加载文章内容,源代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Configuration; using System.Data.SqlClient; using Microsoft.ApplicationBlocks.Data; using System.Data; using System.Text; namespace AJAXPagingTest { /// <summary> /// Summary description for LoadArticle /// </summary> public class LoadArticle : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; //获取连接字符串 String connString = ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString; //获取所要读取的文章编号 String aid = context.Request["article"]; SqlParameter[] sp=new SqlParameter[1]; sp[0]=new SqlParameter("@aid",aid); SqlDataReader dr = SqlHelper.ExecuteReader(connString, CommandType.Text, "select Title,Article from T_Articles where AID=@aid", sp); StringBuilder sb = new StringBuilder(); while (dr.Read()) { sb.Append(dr.GetString(dr.GetOrdinal("Title"))); sb.Append("|"); sb.Append(dr.GetString(dr.GetOrdinal("Article"))); } context.Response.Write(sb.ToString()); } public bool IsReusable { get { return false; } } } }
LoadCommentAndPaging.ashx:也是一个一般处理程序,用于加载评论,源代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Data; using System.Data.SqlClient; using Microsoft.ApplicationBlocks.Data; using System.Configuration; using System.Web.Script.Serialization; namespace AJAXPagingTest { /// <summary> /// Summary description for LoadCommentAndPaging /// </summary> public class LoadCommentAndPaging : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; String connStr = ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString; List<Comment> Comments = new List<Comment>(); String result = String.Empty; //获取页面的动作 String action = context.Request["action"]; //页面第一加载的时候 if (action=="load") { DataTable dt = SqlHelper.ExecuteDataset(connStr, CommandType.Text, "select top(10) * from T_Comments where AID=1").Tables[0]; foreach (DataRow dr in dt.Rows) { Comment comment = new Comment(); comment.Username = dr["Username"].ToString(); comment.Commentz = dr["Comment"].ToString(); Comments.Add(comment); } JavaScriptSerializer jss = new JavaScriptSerializer(); result = jss.Serialize(Comments); context.Response.Write(result); return; } //获取当前页码 String pageString = context.Request["page"]; //处理延时或分页加载评论 if (action=="pageOrlazy") { //获取当前延时加载的次数 String countString = context.Request["count"]; int page, count; //判断参数是否正确 if (int.TryParse(pageString, out page) && int.TryParse(countString, out count)) { //计算需要加载评论的起始索引 int startindex = (page - 1) * 30 + count * 10 + 1; //计算需要加载评论结束索引 int endindex = startindex + 9; SqlParameter[] sp = new SqlParameter[3]; sp[0] = new SqlParameter("@aid", 1); sp[1] = new SqlParameter("@startindex", startindex); sp[2] = new SqlParameter("@endindex", endindex); DataTable dt = SqlHelper.ExecuteDataset(connStr, CommandType.StoredProcedure, "ps_getpageandload", sp).Tables[0]; foreach (DataRow dr in dt.Rows) { Comment comment = new Comment(); comment.Username = dr["Username"].ToString(); comment.Commentz = dr["Comment"].ToString(); Comments.Add(comment); } JavaScriptSerializer jss = new JavaScriptSerializer(); result = jss.Serialize(Comments); context.Response.Write(result); return; } else { throw new Exception("参数传递错误"); } } //获取页码 if (action=="pagenumber") { int number = Convert.ToInt32(SqlHelper.ExecuteScalar(connStr, CommandType.Text, "select count(*) from T_Comments")); context.Response.Write((number/30).ToString()); return; } } public bool IsReusable { get { return false; } } } public class Comment { public String Username {get;set; } public String Commentz {get;set; } } }
CommnetPage.htm:最后是前台页面的JQuery代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> <link href="Style/StyleSheet1.css" rel="stylesheet" type="text/css" /> <script src="JS/jquery-1.4.2.min.js" type="text/javascript"></script> <script type="text/javascript"> $(function () { //加载文章内容 $.post("LoadArticle.ashx", { "article": "1" }, function (data, state) { if (state == "success") { //利用"|"来分隔标题和正文 var article = data.split("|"); $("#article h3").text(article[0]); $("#article").append(article[1]); } }); //加载初始的10条评论条数 $.post("LoadCommentAndPaging.ashx", { "action": "load" }, function (data, state) { if (state == "success") { var comments = $.parseJSON(data); for (var i = 0; i < comments.length; i++) { var comment = "<tr><td>" + comments[i].Username + "说:</td><td>" + comments[i].Commentz + "</td></tr>"; $("#comment").append(comment); } } }); }); //标记页面延迟数 var flag = 1; //标记当前页面 var currentpage = 1; //监测是否需要加载评论 function check(n) { //监测浏览器的模式,根据不同的模式获取客户端高度会有不同 var dom = document.compatMode == "CSS1Compat" ? document.documentElement : document.body; var pre = document.getElementById("preload"); //获取滚动条离顶端的高度,用IE测试时是用 //documentElement.scrollTop获取高度, //而在用chrome测试时是body.scrollTop获取高度 var scrtop = dom.scrollTop || document.body.scrollTop; //传入的参数为当前页数,保存为全局变量 currentpage = n; //当客户端显示窗口离标记的地方小于100距离时开始加载 if (pre.offsetTop - (dom.clientHeight + scrtop) < 100) { $.post("LoadCommentAndPaging.ashx", { "action": "pageOrlazy", "page": currentpage, "count": flag }, function (data, state) { if (state == "success") { var comments = $.parseJSON(data); for (var i = 0; i < comments.length; i++) { var comment = "<tr><td>" + comments[i].Username + "说:</td><td>" + comments[i].Commentz + "</td></tr>"; $("#comment").append(comment); } } }); flag = flag + 1; //如果加载多于3次了则不加载评论了,加载页码 if (flag <= 2) { setTimeout("check(currentpage)", 2000); } else { //加载页码 $.post("LoadCommentAndPaging.ashx", { "action": "pagenumber" }, function (data, state) { if (state == "success") { var count = parseInt(data, 10); for (var i = 1; i <= count + 1; i++) { var control; //等于当前页时则不显示超链接 if (i != currentpage) { control = "<td><a href=''>" + i + "</a></td>"; } else { control = "<td>" + i + "</td>"; } $("#anchorlink").append(control); } //加载分页点击时的事件 $("#anchorlink td").click(function (e) { e.preventDefault(); //阻止超链接的转向 $("#comment").empty(); //将评论区清空 $("#anchorlink").empty(); //将页码清空 $("#preload").text("评论正在加载中..."); flag = 0; var page = parseInt($(this).text()); check(page); }); } }); //去掉“评论加载中”的显示 $("#preload").text(""); } } else { setTimeout("check(currentpage)", 2000); } } //每隔两秒检查一下页面是否需要加载评论 setTimeout("check(currentpage)", 2000); </script> </head> <body> <div id="main"> <div id="article"> <h3> </h3> </div> <div> <table id="comment"> </table> <p id="preload"> 评论正在加载中...</p> <table> <tr id="anchorlink"> </tr> </table> </div> </div> </body> </html>