首先建立資料庫,資料關係圖如下:
本文要實現的效果就是在評論別人文章時,如果文章內容過長或者評論內容過長,實現的一個評論分段消極式載入的效果,即每頁可顯示30條評論,可每隔10條消極式載入一次以提高網頁傳輸顯示效率。
我所實現的頁面延遲的原理如,就是求出X的距離小於100時進行載入延遲的評論,然後又設定了一個標記位,用來判斷消極式載入了多少次,每頁僅能載入30條評論記錄。
然後再評論末端載入上頁碼實現無重新整理進行分頁的效果。
分頁的方法也是比較簡單的,這裡自己實現了一個預存程序,使用到row_number()函數:
ALTER PROCEDURE ps_getpageandload@aid int,@startindex int,@endindex intASselect * from(select Row_Number() over(order by CID) as rownum,Username,Commentfrom T_Comments where AID=@aid) as Twhere T.rownum>=@startindex and T.rownum<=@endindexRETURN
就是輸入一個起始位置的參數和結束位置的參數,取出中間的資料。
這樣,在程式中就好取出資料了,比如:我第一頁就是要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>