透過 jQuery AJAX 搭配 Generic Handler (.ashx) 實現「點擊載入更多」的無刷新分頁體驗,適用於新聞列表、留言板等場景。
<div id="newsContainer"></div>
<button id="btnLoadMore" class="get_more">查看更多</button>
<div id="divload" style="display:none;">載入中...</div>
<div id="more2"></div>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(function () {
var count = 5; // 每次載入筆數
var start = 0; // 起始索引
function loadMore() {
$.ajax({
type: "GET",
dataType: "json",
url: "Handler/NewsHandler.ashx",
data: { action: "GetMoreNews", count: count, start: start },
beforeSend: function () {
$("#divload").show();
$("#btnLoadMore").hide();
},
complete: function () {
$("#divload").hide();
$("#btnLoadMore").show();
},
success: function (json) {
if (!json || json.length === 0) {
$("#more2").html("沒有更多內容了……");
$("#btnLoadMore").hide();
return;
}
$.each(json, function (i, item) {
var html = "<div class='single_item'>"
+ "<div class='element_head'>"
+ "<div class='author'>" + item.Title + "</div>"
+ "<div class='date'>" + item.Date + "</div>"
+ "</div>"
+ "<div class='content'>" + item.Contents + "</div>"
+ "</div>";
$("#newsContainer").append(html);
});
start += count; // 更新下一次起始位置
}
});
}
// 初始載入
loadMore();
// 點擊載入更多
$("#btnLoadMore").click(loadMore);
});
</script>
public class NewsHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "application/json";
string action = context.Request["action"];
if (action == "GetMoreNews")
{
int count = int.Parse(context.Request["count"]);
int start = int.Parse(context.Request["start"]);
var list = NewsManager.GetNewsPage(count, start); // 回傳 List
// 使用 Newtonsoft.Json 序列化
string json = JsonConvert.SerializeObject(list);
context.Response.Write(json);
}
}
public bool IsReusable => false;
}
public static IList<News> GetNewsPage(int pageSize, int offset)
{
using (SqlConnection cn = new SqlConnection(connStr))
{
cn.Open();
// SQL Server 2012+ 可用 OFFSET FETCH,舊版用 NOT IN 子查詢
string sql = @"
SELECT TOP @pageSize *
FROM tb_News
WHERE Id NOT IN (SELECT TOP @offset Id FROM tb_News ORDER BY Id DESC)
ORDER BY Id DESC";
using (SqlCommand cmd = new SqlCommand(sql, cn))
{
cmd.Parameters.AddWithValue("@pageSize", pageSize);
cmd.Parameters.AddWithValue("@offset", offset);
using (SqlDataReader dr = cmd.ExecuteReader())
{
var list = new List<News>();
while (dr.Read())
{
list.Add(new News
{
ID = (int)dr["ID"],
Title = dr["Title"].ToString(),
Contents = dr["Contents"].ToString(),
Picture = dr["Picture"].ToString(),
Date = ((DateTime)dr["Date"]).ToString("yyyy-MM-dd HH:mm:ss")
});
}
return list;
}
}
}
}

OFFSET @offset ROWS FETCH NEXT @pageSize ROWS ONLY (SQL 2012+) 效能更佳。