Asp.net使用JQuery实现评论的无刷新分页及分段延迟加载效果
首先建立数据库,数据关系图如下:

本文要实现的效果就是在评论别人文章时,如果文章内容过长或者评论内容过长,实现的一个评论分段延迟加载的效果,即每页可显示30条评论,可每隔10条延迟加载一次以提高网页传输显示效率。
我所实现的页面延迟的原理如下图,就是求出X的距离小于100时进行加载延迟的评论,然后又设置了一个标记位,用来判断延迟加载了多少次,每页仅能加载30条评论记录。

然后再评论末端加载上页码实现无刷新进行分页的效果。
分页的方法也是比较简单的,这里自己实现了一个存储过程,使用到row_number()函数:
01 |
ALTER PROCEDURE ps_getpageandload |
02 |
@aid int, |
03 |
@startindex int, |
04 |
@endindex int |
05 |
AS |
06 |
select * from |
07 |
( |
08 |
select Row_Number() over(order by CID) as rownum,Username,Comment |
09 |
from T_Comments where AID=@aid |
10 |
) as T |
11 |
where T.rownum>=@startindex and T.rownum<=@endindex |
12 |
RETURN |
就是输入一个起始位置的参数和结束位置的参数,取出中间的数据。
这样,在程序中就好取出数据了,比如:我第一页就是要1-30的数据,就让startindex=1,endindex=30就行了;第二页就是31-60的数据,同理。
LoadArticle.ashx:一个一般处理程序,用来加载文章内容,源代码如下:
01 |
using System; |
02 |
using System.Collections.Generic; |
03 |
using System.Linq; |
04 |
using System.Web; |
05 |
using System.Configuration; |
06 |
using System.Data.SqlClient; |
07 |
using Microsoft.ApplicationBlocks.Data; |
08 |
using System.Data; |
09 |
using System.Text; |
10 |
|
11 |
namespace AJAXPagingTest |
12 |
{ |
13 |
/// <summary> |
14 |
/// Summary description for LoadArticle |
15 |
/// </summary> |
16 |
public class LoadArticle : IHttpHandler |
17 |
{ |
18 |
|
19 |
public void ProcessRequest(HttpContext context) |
20 |
{ |
21 |
context.Response.ContentType = "text/plain"; |
22 |
|
23 |
//获取连接字符串 |
24 |
String connString = ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString; |
25 |
|
26 |
//获取所要读取的文章编号 |
27 |
String aid = context.Request["article"]; |
28 |
SqlParameter[] sp=new SqlParameter[1]; |
29 |
sp[0]=new SqlParameter("@aid",aid); |
30 |
|
31 |
SqlDataReader dr = SqlHelper.ExecuteReader(connString, |
32 |
CommandType.Text, |
33 |
"select Title,Article from T_Articles where AID=@aid", |
34 |
sp); |
35 |
|
36 |
StringBuilder sb = new StringBuilder(); |
37 |
|
38 |
while (dr.Read()) |
39 |
{ |
40 |
sb.Append(dr.GetString(dr.GetOrdinal("Title"))); |
41 |
sb.Append("|"); |
42 |
sb.Append(dr.GetString(dr.GetOrdinal("Article"))); |
43 |
} |
44 |
|
45 |
context.Response.Write(sb.ToString()); |
46 |
|
47 |
} |
48 |
|
49 |
public bool IsReusable |
50 |
{ |
51 |
get |
52 |
{ |
53 |
return false; |
54 |
} |
55 |
} |
56 |
} |
57 |
} |
LoadCommentAndPaging.ashx:也是一个一般处理程序,用于加载评论,源代码如下:
001 |
using System; |
002 |
using System.Collections.Generic; |
003 |
using System.Linq; |
004 |
using System.Web; |
005 |
using System.Data; |
006 |
using System.Data.SqlClient; |
007 |
using Microsoft.ApplicationBlocks.Data; |
008 |
using System.Configuration; |
009 |
using System.Web.Script.Serialization; |
010 |
|
011 |
|
012 |
namespace AJAXPagingTest |
013 |
{ |
014 |
/// <summary> |
015 |
/// Summary description for LoadCommentAndPaging |
016 |
/// </summary> |
017 |
public class LoadCommentAndPaging : IHttpHandler |
018 |
{ |
019 |
|
020 |
public void ProcessRequest(HttpContext context) |
021 |
{ |
022 |
context.Response.ContentType = "text/plain"; |
023 |
|
024 |
String connStr = ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString; |
025 |
List<Comment> Comments = new List<Comment>(); |
026 |
String result = String.Empty; |
027 |
|
028 |
//获取页面的动作 |
029 |
String action = context.Request["action"]; |
030 |
|
031 |
//页面第一加载的时候 |
032 |
if (action=="load") |
033 |
{ |
034 |
DataTable dt = SqlHelper.ExecuteDataset(connStr, |
035 |
CommandType.Text, |
036 |
"select top(10) * from T_Comments where AID=1").Tables[0]; |
037 |
|
038 |
foreach (DataRow dr in dt.Rows) |
039 |
{ |
040 |
Comment comment = new Comment(); |
041 |
comment.Username = dr["Username"].ToString(); |
042 |
comment.Commentz = dr["Comment"].ToString(); |
043 |
Comments.Add(comment); |
044 |
} |
045 |
JavaScriptSerializer jss = new JavaScriptSerializer(); |
046 |
result = jss.Serialize(Comments); |
047 |
context.Response.Write(result); |
048 |
return; |
049 |
} |
050 |
|
051 |
//获取当前页码 |
052 |
String pageString = context.Request["page"]; |
053 |
|
054 |
//处理延时或分页加载评论 |
055 |
if (action=="pageOrlazy") |
056 |
{ |
057 |
//获取当前延时加载的次数 |
058 |
String countString = context.Request["count"]; |
059 |
|
060 |
int page, count; |
061 |
|
062 |
//判断参数是否正确 |
063 |
if (int.TryParse(pageString, out page) && int.TryParse(countString, out count)) |
064 |
{ |
065 |
//计算需要加载评论的起始索引 |
066 |
int startindex = (page - 1) * 30 + count * 10 + 1; |
067 |
|
068 |
//计算需要加载评论结束索引 |
069 |
int endindex = startindex + 9; |
070 |
|
071 |
SqlParameter[] sp = new SqlParameter[3]; |
072 |
sp[0] = new SqlParameter("@aid", 1); |
073 |
sp[1] = new SqlParameter("@startindex", startindex); |
074 |
sp[2] = new SqlParameter("@endindex", endindex); |
075 |
|
076 |
DataTable dt = SqlHelper.ExecuteDataset(connStr, |
077 |
CommandType.StoredProcedure, |
078 |
"ps_getpageandload", |
079 |
sp).Tables[0]; |
080 |
|
081 |
foreach (DataRow dr in dt.Rows) |
082 |
{ |
083 |
Comment comment = new Comment(); |
084 |
comment.Username = dr["Username"].ToString(); |
085 |
comment.Commentz = dr["Comment"].ToString(); |
086 |
Comments.Add(comment); |
087 |
} |
088 |
|
089 |
JavaScriptSerializer jss = new JavaScriptSerializer(); |
090 |
result = jss.Serialize(Comments); |
091 |
context.Response.Write(result); |
092 |
return; |
093 |
|
094 |
} |
095 |
else |
096 |
{ |
097 |
throw new Exception("参数传递错误"); |
098 |
} |
099 |
|
100 |
} |
101 |
|
102 |
//获取页码 |
103 |
if (action=="pagenumber") |
104 |
{ |
105 |
int number = Convert.ToInt32(SqlHelper.ExecuteScalar(connStr, |
106 |
CommandType.Text, |
107 |
"select count(*) from T_Comments")); |
108 |
|
109 |
context.Response.Write((number/30).ToString()); |
110 |
return; |
111 |
} |
112 |
|
113 |
|
114 |
} |
115 |
|
116 |
public bool IsReusable |
117 |
{ |
118 |
get |
119 |
{ |
120 |
return false; |
121 |
} |
122 |
} |
123 |
} |
124 |
|
125 |
public class Comment |
126 |
{ |
127 |
public String Username {get;set; } |
128 |
public String Commentz {get;set; } |
129 |
} |
130 |
} |
CommnetPage.htm:最后是前台页面的JQuery代码
001 |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
002 |
<html xmlns="http://www.w3.org/1999/xhtml"> |
003 |
<head> |
004 |
<title></title> |
005 |
<link href="Style/StyleSheet1.css" rel="stylesheet" type="text/css" /> |
006 |
<script src="JS/jquery-1.4.2.min.js" type="text/javascript"></script> |
007 |
<script type="text/javascript"> |
008 |
$(function () { |
009 |
|
010 |
//加载文章内容 |
011 |
$.post("LoadArticle.ashx", { "article": "1" }, function (data, state) { |
012 |
if (state == "success") { |
013 |
|
014 |
//利用"|"来分隔标题和正文 |
015 |
var article = data.split("|"); |
016 |
$("#article h3").text(article[0]); |
017 |
$("#article").append(article[1]); |
018 |
} |
019 |
}); |
020 |
|
021 |
//加载初始的10条评论条数 |
022 |
$.post("LoadCommentAndPaging.ashx", { "action": "load" }, function (data, state) { |
023 |
if (state == "success") { |
024 |
var comments = $.parseJSON(data); |
025 |
|
026 |
for (var i = 0; i < comments.length; i++) { |
027 |
var comment = "<tr><td>" + comments[i].Username + "说:</td><td>" + comments[i].Commentz + "</td></tr>"; |
028 |
$("#comment").append(comment); |
029 |
} |
030 |
} |
031 |
}); |
032 |
}); |
033 |
|
034 |
//标记页面延迟数 |
035 |
var flag = 1; |
036 |
|
037 |
//标记当前页面 |
038 |
var currentpage = 1; |
039 |
|
040 |
//监测是否需要加载评论 |
041 |
function check(n) { |
042 |
|
043 |
//监测浏览器的模式,根据不同的模式获取客户端高度会有不同 |
044 |
var dom = document.compatMode == "CSS1Compat" ? document.documentElement : document.body; |
045 |
var pre = document.getElementById("preload"); |
046 |
|
047 |
//获取滚动条离顶端的高度,用IE测试时是用 |
048 |
//documentElement.scrollTop获取高度, |
049 |
//而在用chrome测试时是body.scrollTop获取高度 |
050 |
var scrtop = dom.scrollTop || document.body.scrollTop; |
051 |
|
052 |
//传入的参数为当前页数,保存为全局变量 |
053 |
currentpage = n; |
054 |
|
055 |
//当客户端显示窗口离标记的地方小于100距离时开始加载 |
056 |
if (pre.offsetTop - (dom.clientHeight + scrtop) < 100) { |
057 |
$.post("LoadCommentAndPaging.ashx", { "action": "pageOrlazy", "page": currentpage, "count": flag }, function (data, state) { |
058 |
if (state == "success") { |
059 |
var comments = $.parseJSON(data); |
060 |
for (var i = 0; i < comments.length; i++) { |
061 |
var comment = "<tr><td>" + comments[i].Username + "说:</td><td>" + comments[i].Commentz + "</td></tr>"; |
062 |
$("#comment").append(comment); |
063 |
} |
064 |
} |
065 |
}); |
066 |
|
067 |
flag = flag + 1; |
068 |
|
069 |
//如果加载多于3次了则不加载评论了,加载页码 |
070 |
if (flag <= 2) { |
071 |
setTimeout("check(currentpage)", 2000); |
072 |
} |
073 |
else { |
074 |
//加载页码 |
075 |
$.post("LoadCommentAndPaging.ashx", { "action": "pagenumber" }, function (data, state) { |
076 |
if (state == "success") { |
077 |
var count = parseInt(data, 10); |
078 |
|
079 |
for (var i = 1; i <= count + 1; i++) { |
080 |
var control; |
081 |
|
082 |
//等于当前页时则不显示超链接 |
083 |
if (i != currentpage) { |
084 |
control = "<td><a href=''>" + i + "</a></td>"; |
085 |
} |
086 |
else { |
087 |
control = "<td>" + i + "</td>"; |
088 |
} |
089 |
|
090 |
|
091 |
$("#anchorlink").append(control); |
092 |
|
093 |
|
094 |
} |
095 |
//加载分页点击时的事件 |
096 |
$("#anchorlink td").click(function (e) { |
097 |
e.preventDefault(); //阻止超链接的转向 |
098 |
$("#comment").empty(); //将评论区清空 |
099 |
$("#anchorlink").empty(); //将页码清空 |
100 |
$("#preload").text("评论正在加载中..."); |
101 |
flag = 0; |
102 |
var page = parseInt($(this).text()); |
103 |
check(page); |
104 |
|
105 |
}); |
106 |
|
107 |
} |
108 |
}); |
109 |
//去掉“评论加载中”的显示 |
110 |
$("#preload").text(""); |
111 |
} |
112 |
} |
113 |
else { |
114 |
setTimeout("check(currentpage)", 2000); |
115 |
} |
116 |
|
117 |
} |
118 |
|
119 |
//每隔两秒检查一下页面是否需要加载评论 |
120 |
setTimeout("check(currentpage)", 2000); |
121 |
|
122 |
</script> |
123 |
</head> |
124 |
<body> |
125 |
<div id="main"> |
126 |
<div id="article"> |
127 |
<h3> |
128 |
</h3> |
129 |
</div> |
130 |
<div> |
131 |
<table id="comment"> |
132 |
</table> |
133 |
<p id="preload"> |
134 |
评论正在加载中...</p> |
135 |
<table> |
136 |
<tr id="anchorlink"> |
137 |
</tr> |
138 |
</table> |
139 |
</div> |
140 |
</div> |
141 |
</body> |
142 |
</html> |

浙公网安备 33010602011771号