.NET技术交流群:337901356 ,欢迎您的加入!
对 于一个用户体验好的网站来说,无刷新技术是很重要的,无刷新,顾名思义,就是局部刷新数据,有用过Asp.net Web Form技术开发网页的人,可能对服务器端(具有runat="server"属性)的控件的回发(PostBack)特性有一定的了解。我们知道,只要 一点击页面中的Asp.net按钮(可能是LinkButton,也可能是Button,还有可能是ImageButton等)都会引起整个页面的刷新, 这样的体验是非常不好的,因为点击按钮后导致的操作是重新给服务器发送一个请求,重新执行一次页面的服务端代码,重新生成html,然后响应生成的页面内 容,发回浏览器端。这样无形中增大了网络浏览,用户等待页面的响应时间增长等。 有时我们点击某个按钮目的只是为了某个区域的数据被更新,而其他的区域的数据不变,这个时候我们就可以使用Ajax技术(Asynchronous Javascript And XML)称为异步Javascript 和 XML. 但是往往我们站点中的数据不止一条,但又要有页面无刷新(其实是局部刷新)的效果,那么分页的时候我们就不能在网上去下载服务端的分页控件(如 AspNetPager)来进行分页,因为服务器端的分页控件会和后台相关联,只能通过Javascript代码来编写一个分页控件来进行分页。 废话不多话说,看分页代码。 为了证明是无刷新分页,这里我们page.html这个静态页面来呈现从数据库中取到的数据。 page.html页面代码如下
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> <link href="../分页控件/Page.css" rel="stylesheet" /> <script src="../分页控件/Page.js"></script> <style type="text/css"> .b { color: red; text-align: center; margin-top: 100px; } th { padding: 10px; } .td { border-left: 1px solid #E0E0E0; border-top: 1px solid #E0E0E0; padding: 10px; color: Brown; text-align: center; } .table { border-bottom: 1px solid #E0E0E0; border-right: 1px solid #E0E0E0; width: 80%; } </style> </head> <body> <div style="800px;margin:0px auto;border:1px solid Gray;height:1000px;"> <!--用于呈现要显示的数据的div--> <div id="content" style="height:auto;"> <!--<select id="sel"></select>--> </div> <!--用于呈现分页控件的Div--> <div id="pager"> </div>
<script type="text/javascript">
var totalRecord = 0;
var xmlHttpRequest = new XMLHttpRequest();
xmlHttpRequest.open("get", "../ashx文件/GetRecordCount.ashx", true);
xmlHttpRequest.onreadystatechange = function () {
if (xmlHttpRequest.readyState == 4 && xmlHttpRequest.status == "200") {
totalRecord = parseInt(xmlHttpRequest.responseText, 10);
InitializePageControl(10, totalRecord, function () {
var xmlHttp = new XMLHttpRequest();
xmlHttp.open("get", "../aspx页面/GetProduct.aspx?pageIndex=" + (this.pageIndex) + "&pageSize=" + (this.pageSize), true);
xmlHttp.onreadystatechange = function () {
if (xmlHttp.readyState == 4 && xmlHttp.status == "200") {
var content = document.getElementById("content");
content.innerHTML = "";
content.innerHTML = xmlHttp.responseText;
}
}
xmlHttp.send(null);
}, document.getElementById("pager"));
}
}
xmlHttpRequest.send(null);
</script>
</div> </body> </html> 返回数据的页面:GetProduct.aspx页面
:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="GetProduct.aspx.cs" Inherits="开源代码.aspx页面.GetProduct" %> <asp:repeater id="Repeater1" runat="server"> <HeaderTemplate> <table class="table"> <tr> <th>编号</th> <th>姓名</th> <th>产品编号</th> <th>颜色</th> </tr> </HeaderTemplate> <ItemTemplate> <tr> <td class="td"><%#Eval("ProductID") %></td> <td class="td"><%#Eval("Name") %></td> <td class="td"><%#Eval("ProductNumber") %></td> <td class="td"><%#Eval("Color") %></td> </tr> </ItemTemplate> <FooterTemplate> </table> </FooterTemplate> </asp:repeater>
GetProduct.aspx.cs: using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Linq; using System.Web; using System.Web.Script.Serialization; using System.Web.UI; using System.Web.UI.WebControls; namespace 开源代码.aspx页面 { public partial class GetProduct : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { Bind(); } } private void Bind() { string pageIndex = Request.QueryString["pageIndex"]; int pageSize = int.Parse(Request.QueryString["pageSize"]); if (!string.IsNullOrEmpty(pageIndex)) { int p = int.Parse(pageIndex); using (SqlConnection conn = new SqlConnection("Data Source=chenxin-pc;Initial Catalog=AdventureWorks;Integrated Security=True")) { using (SqlCommand comm = conn.CreateCommand()) { try { comm.CommandText = "with tmp as (select Row_Number() over(order by ProductID) RowIndex,* from Production.Product) select * from tmp where RowIndex between " + ((p - 1) * pageSize) + " and " + (p * pageSize); SqlDataAdapter adapter = new SqlDataAdapter(comm); DataTable dt = new DataTable(); adapter.Fill(dt); this.Repeater1.DataSource = dt; this.Repeater1.DataBind(); } catch (Exception ex) { Response.Write("服务器内部异常!"); } } } } else { Response.Write("请求的页错误!"); } } } }
最后:Page.js代码如下 //用于初始化页面,调用该方法,使得第一次进入页面时加载第一页数据,并且初始化分页控件。 //pageSize:每页要显示几条记录。 //totalRecord:总共有多少条记录。 //clickFunction:点击分页按钮时要执行的函数。 //containers:一个Dom对象,表示要将分页控件呈现在哪一个元素中。 function InitializePageControl(pageSize, totalRecord, clickFunction, container) { this.pageIndex = 1; this.pageSize = pageSize; clickFunction.call(this); PageControl(1, pageSize, totalRecord, clickFunction, container); } //根据参数来创建一个超链接 function createAnchor(params) { var a = document.createElement("a"); for (var attr in params) { a[attr] = params[attr]; } return a; } //pageIndex:当前要显示的是第几页。 //pageSize:每页要显示几条记录。 //totalRecord:总共有多少条记录。 //clickFunction:点击分页按钮时要执行的函数。 //containers:一个Dom对象,表示要将分页控件呈现在哪一个元素中。 function PageControl(pageIndex, pageSize, totalRecord, clickFunction, container) { container.innerHTML = ""; if (totalRecord <= 0) { return false; } var divContainer = document.createElement("div"); divContainer.className = "divContainer"; //函数func用于用户点击每一个分页按钮时,PageControl内部要处理的函数。 var func = function () { //当前这个this是指被点击的分页按钮中的某个超链接对象。 this.pageSize = pageSize; clickFunction.call(this); PageControl(this.pageIndex, pageSize, totalRecord, clickFunction, container); }; //求出总共多少页 var pageCount = Math.ceil(totalRecord / pageSize); //上一页的超链接 只有总页数大于2页,并且当前显示的页不是第一页的时候才显示上一页 if (pageCount > 2 && pageIndex != 1) { var previousPage = createAnchor( { "id": "previousPage", "href": "#", "className": "a", "innerHTML": "上一页", "onclick": func, "pageIndex": pageIndex - 1 } ); divContainer.appendChild(previousPage); } var params = { "href": "#", "className": "a", "onclick": func } //如果总页数大于8页,则要出现...的形式。 if (pageCount > 8) { var firstPage = createAnchor({ "href": "#", "className": "a", "innerHTML": 1, "pageIndex": 1, "onclick": func }); var lastPage = createAnchor({ "href": "#", "className": "a", "innerHTML": pageCount, "pageIndex": pageCount, "onclick": func }); if (pageIndex > 4 && pageIndex + 4 <= pageCount) { divContainer.appendChild(firstPage); var a = createAnchor({ "innerHTML": "..." }); divContainer.appendChild(a); for (var i = pageIndex - 2; i <= pageIndex + 2; i++) { params.className = "a"; params.innerHTML = i.toString(); params.pageIndex = i; if (i == pageIndex) { params.className += " current"; } a = createAnchor(params); divContainer.appendChild(a); } a = createAnchor({ "innerHTML": "..." }); divContainer.appendChild(a); divContainer.appendChild(lastPage); }//当前要显示的页数<=4页 else if (pageIndex <= 4) { for (var i = 1; i <= 6; i++) { params.className = "a"; params.innerHTML = i.toString(); params.pageIndex = i; if (i == pageIndex) { params.className += " current"; } a = createAnchor(params); divContainer.appendChild(a); } a = createAnchor({ "innerHTML": "..." }); divContainer.appendChild(a); divContainer.appendChild(lastPage); }//当前要显示的是最后一页。 else { divContainer.appendChild(firstPage); a = createAnchor({ "innerHTML": "...", "className": "a" }); divContainer.appendChild(a); for (var i = pageCount - 5; i <= pageCount; i++) { params.className = "a"; params.innerHTML = i.toString(); params.pageIndex = i; if (i == pageIndex) { params.className += " current";//不要漏了current前面的空格哦 } a = createAnchor(params); divContainer.appendChild(a); } } }//总页数<=8页,那么就直接显示所有的页数 else { for (var i = 1; i <= pageCount; i++) { params.className = "a"; params.innerHTML = i.toString(); params.pageIndex = i; if (i == pageIndex) { params.className += " current"; } a = createAnchor(params); divContainer.appendChild(a); } } //之用总页数大于2页,并且当前显示的页<总页数的时候才显示下一页 if (pageCount >= 2 && pageIndex < pageCount) { var nextPage = createAnchor( { "id": "nextPage", "href": "#", "className": "a", "innerHTML": "下一页", "onclick": func, "pageIndex": (pageIndex + 1) } ); divContainer.appendChild(nextPage); } var span = document.createElement("span"); span.textContent = "转到"; span.className = "span"; divContainer.appendChild(span); var input = document.createElement("input"); input.type = "text"; input.value = pageIndex.toString(); input.id = "txtPageIndex"; input.className = "input"; divContainer.appendChild(input); span = document.createElement("span"); span.innerHTML = "页"; span.className = "span"; divContainer.appendChild(span); var go = document.createElement("input"); go.type = "button"; go.className = "go"; go.value = "Go"; go.onclick = function () { var txtPageIndex = document.getElementById("txtPageIndex"); try { //alert("value" in txtPageIndex); var pageIndex = parseInt(txtPageIndex.value, 10); if (pageIndex < 1 || pageIndex > pageCount) { alert("页数的合法范围: 1-" + pageCount); } else if (isNaN(pageIndex)) { alert("页数必须为数字!"); } else { //这里面的this是指input,但是因为input这个东西并没有pageIndex属性,所以我们必须给其添加进去 this.pageIndex = pageIndex; this.pageSize = pageSize; clickFunction.call(this); PageControl(pageIndex, pageSize, totalRecord, clickFunction, container); } } catch (error) { alert("描述:" + error.description + " 详细信息: " + error.stack + error.message); } } divContainer.appendChild(go); container.appendChild(divContainer); }