首先建立數據庫,數據關係圖如下:
本文要實現的效果就是在評論別人文章時,如果文章內容過長或者評論內容過長,實現的一個評論分段延遲加載的效果,即每頁可顯示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>