进一步了解XMLHttpRequest对象,包括如下属性:
onreadystatechange:每次状态改变所触发事件的事件处理程序。
responseText:从服务器进程返回数据的字符串形式。
responseXML:从服务器进程返回的DOM兼容的文档数据对象。
status:从服务器返回的数字代码,比如常见的404(未找到)和200(已就绪)
status Text:伴随状态码的字符串信息。
readyState:状态值0、未初始化,对象已建立,但是尚未初始化(尚未调用open方法)
1、初始化,对象已建立,尚未调用send方法
2、发送数据,send方法已调用,但是当前的状态及http头未知
3、数据传送中,已接收部分数据,因为响应及http头不全,这时通过responseBody和responseText获取部分数据会出现错误
4、完成,数据接收完毕,此时可以通过通过responseXml和responseText获取完整的响应数据
先看一个简单的URL请求:
View Code
//
创建XMLHttpRequest,不同浏览器调用的创建方法不一样
function XmlHttpRequest(){
var requestObj = null ;
if (window.XMLHttpRequest){
requestObj = new XMLHttpRequest();
} else {
try {
requestObj = new ActiveXObject( ' MSXML2.XMLHTTP.4.0 ' );
} catch (e){
try {
requestObj = new ActiveXObject( ' MSXML2.XMLHTTP.3.0 ' );
} catch (e){
try {
requestObj = new ActiveXObject( ' MSXML2.XMLHTTP.2.6 ' );
} catch (e){
try {
requestObj = new ActiveXObject( ' MSXML2.XMLHTTP ' );
} catch (e){
try {
requestObj = new ActiveXObject( ' Microsoft.XMLHTTP ' );
} catch (e){}
}
}
}
}
}
if (requestObj == null ){
alert( ' The browser does not surport XMLHTTP. ' );
}
return requestObj;
}
// 发起POST请求并接收响应数据
function GetData(){
var xmlhttp = XmlHttpRequest();
if ( ! xmlhttp){
alert( ' 创建xmlhttp对象异常! ' );
return ;
}
var url = ' AjaxHandler/ProcPager.aspx ' ;
xmlhttp.open( ' POST ' , url, false );
xmlhttp.onreadystatechange = function (){
if (xmlhttp.readyState == 4 ){
document.getElementById( ' divPager ' ).innerHTML = ' 数据加载中,请稍候... ' ;
if (xmlhttp.status == 200 ){
document.getElementById( ' divPager ' ).innerHTML = xmlhttp.responseText;
}
}
}
xmlhttp.send();
}
function XmlHttpRequest(){
var requestObj = null ;
if (window.XMLHttpRequest){
requestObj = new XMLHttpRequest();
} else {
try {
requestObj = new ActiveXObject( ' MSXML2.XMLHTTP.4.0 ' );
} catch (e){
try {
requestObj = new ActiveXObject( ' MSXML2.XMLHTTP.3.0 ' );
} catch (e){
try {
requestObj = new ActiveXObject( ' MSXML2.XMLHTTP.2.6 ' );
} catch (e){
try {
requestObj = new ActiveXObject( ' MSXML2.XMLHTTP ' );
} catch (e){
try {
requestObj = new ActiveXObject( ' Microsoft.XMLHTTP ' );
} catch (e){}
}
}
}
}
}
if (requestObj == null ){
alert( ' The browser does not surport XMLHTTP. ' );
}
return requestObj;
}
// 发起POST请求并接收响应数据
function GetData(){
var xmlhttp = XmlHttpRequest();
if ( ! xmlhttp){
alert( ' 创建xmlhttp对象异常! ' );
return ;
}
var url = ' AjaxHandler/ProcPager.aspx ' ;
xmlhttp.open( ' POST ' , url, false );
xmlhttp.onreadystatechange = function (){
if (xmlhttp.readyState == 4 ){
document.getElementById( ' divPager ' ).innerHTML = ' 数据加载中,请稍候... ' ;
if (xmlhttp.status == 200 ){
document.getElementById( ' divPager ' ).innerHTML = xmlhttp.responseText;
}
}
}
xmlhttp.send();
}
看看C#的分页,C#中用于分页的承载控件有很多,DataList、GridView、Repeater等。DataList、GridView天然支持分页,Repeater只能承载数据,没有分页功能,但利用PagedDataSource对象可让其实现分页功能。
对于分页方式,可以通过Sql每次读取指定条数的记录,或者读取出所有记录,在内存中进行分页,下面是两种分页方式的实现:
View Code
//
分页存储过程
CREATE PROCEDURE [dbo].[PROC_PAGER]
@TABLE_NAME VARCHAR( 2048 ), -- 表名或视图表
@COLUMNS VARCHAR( 1024 ), -- 欲选择字段列表
@WHERE VARCHAR( 2000 ), -- 查询条件
@ORDER_BY VARCHAR( 1000 ), -- 排序表达式
@PAGE_INDEX INT, -- 页号,从1开始
@PAGE_SIZE INT, -- 页尺寸
@RECORD_COUNT INT OUTPUT
AS
BEGIN
IF @COLUMNS IS NULL OR LTRIM(RTRIM(@COLUMNS)) = ''
BEGIN
SET @COLUMNS = ' * '
END
DECLARE @SQL_RECORD NVARCHAR( 2000 )
SET @SQL_RECORD = ' SELECT @RECORD_COUNT = COUNT(0) FROM [ ' + @TABLE_NAME + ' ] WHERE 1 = 1 ' + @WHERE
EXEC SP_EXECUTESQL @SQL_RECORD, N ' @RECORD_COUNT INT OUTPUT ' , @RECORD_COUNT OUTPUT
SET @ORDER_BY = ' ORDER BY ' + @ORDER_BY
IF @PAGE_INDEX < 1
BEGIN
SET @PAGE_INDEX = 1
END
IF @PAGE_SIZE < 1
BEGIN
SET @PAGE_SIZE = 10
END
DECLARE @SQL_TEXT VARCHAR(MAX)
SET @SQL_TEXT = ' SELECT ' + @COLUMNS + ' , ROWNUMBER
FROM (
SELECT ' + @COLUMNS + ' , ROW_NUMBER() OVER( ' + @ORDER_BY + ' ) AS ROWNUMBER
FROM [ ' + @TABLE_NAME + ' ]
WHERE 1 = 1 ' + @WHERE + '
) AS T
WHERE ROWNUMBER BETWEEN ' + STR(((@PAGE_INDEX - 1)* @PAGE_SIZE+1)) + ' AND ' + STR(@PAGE_INDEX * @PAGE_SIZE)
SET NOCOUNT ON
EXECUTE(@SQL_TEXT)
SET NOCOUNT OFF
RETURN @@RowCount
END
/// <summary>
/// DataTable分页
/// </summary>
public static DataTable DataTablePager(DataTable dt, int pageSize, int currentPage)
{
DataTable dtRet = dt.Clone();
int records = dt.Rows.Count;
int start = pageSize * (currentPage - 1 );
int end = pageSize * currentPage;
if (end > records)
{
end = records;
}
DataRowCollection drc = dt.Rows;
for ( int i = start; i < end; i ++ )
{
dtRet.ImportRow(drc[i]);
}
return dtRet;
}
CREATE PROCEDURE [dbo].[PROC_PAGER]
@TABLE_NAME VARCHAR( 2048 ), -- 表名或视图表
@COLUMNS VARCHAR( 1024 ), -- 欲选择字段列表
@WHERE VARCHAR( 2000 ), -- 查询条件
@ORDER_BY VARCHAR( 1000 ), -- 排序表达式
@PAGE_INDEX INT, -- 页号,从1开始
@PAGE_SIZE INT, -- 页尺寸
@RECORD_COUNT INT OUTPUT
AS
BEGIN
IF @COLUMNS IS NULL OR LTRIM(RTRIM(@COLUMNS)) = ''
BEGIN
SET @COLUMNS = ' * '
END
DECLARE @SQL_RECORD NVARCHAR( 2000 )
SET @SQL_RECORD = ' SELECT @RECORD_COUNT = COUNT(0) FROM [ ' + @TABLE_NAME + ' ] WHERE 1 = 1 ' + @WHERE
EXEC SP_EXECUTESQL @SQL_RECORD, N ' @RECORD_COUNT INT OUTPUT ' , @RECORD_COUNT OUTPUT
SET @ORDER_BY = ' ORDER BY ' + @ORDER_BY
IF @PAGE_INDEX < 1
BEGIN
SET @PAGE_INDEX = 1
END
IF @PAGE_SIZE < 1
BEGIN
SET @PAGE_SIZE = 10
END
DECLARE @SQL_TEXT VARCHAR(MAX)
SET @SQL_TEXT = ' SELECT ' + @COLUMNS + ' , ROWNUMBER
FROM (
SELECT ' + @COLUMNS + ' , ROW_NUMBER() OVER( ' + @ORDER_BY + ' ) AS ROWNUMBER
FROM [ ' + @TABLE_NAME + ' ]
WHERE 1 = 1 ' + @WHERE + '
) AS T
WHERE ROWNUMBER BETWEEN ' + STR(((@PAGE_INDEX - 1)* @PAGE_SIZE+1)) + ' AND ' + STR(@PAGE_INDEX * @PAGE_SIZE)
SET NOCOUNT ON
EXECUTE(@SQL_TEXT)
SET NOCOUNT OFF
RETURN @@RowCount
END
/// <summary>
/// DataTable分页
/// </summary>
public static DataTable DataTablePager(DataTable dt, int pageSize, int currentPage)
{
DataTable dtRet = dt.Clone();
int records = dt.Rows.Count;
int start = pageSize * (currentPage - 1 );
int end = pageSize * currentPage;
if (end > records)
{
end = records;
}
DataRowCollection drc = dt.Rows;
for ( int i = start; i < end; i ++ )
{
dtRet.ImportRow(drc[i]);
}
return dtRet;
}
了解原理后,可以就分页功能进行实施,思路如下:
1、Web页中定义分页数据的承载区域,用于显示分页输出。
2、建立专用ASPX页,只输出分页内容及导航。
3、建立JS分页对象,用于发起Ajax请求(请求地址为专用的分页ASPX页面),将获取到的内容加载到承载区域进行呈现。
看看具体的实现,为Repeater实现分页功能,我们自己实现一个分页的自定义控件,主要功能就是根据总页数、当前页、每页大小计算出分页导航并输出,同时将PagedDataSource与页面中的Repeater进行绑定,再利用Ajax进行无刷新分页,原理简单,计算稍微麻烦,不多做解释,自己看代码:
View Code
///
<summary>
/// Repeater分页控件
/// </summary>
[ToolboxData( " <{0}:FMPager runat=\"server\" /> " )]
public class FMPager : WebControl, INamingContainer
{
protected static readonly string navigateClassFmt = " <div class=\"pageClass\">{0}</div> " ;
protected static readonly string navigatePageTotalFmt = " <div class=\"pagetotal\">总记录:<strong>{0}</strong> 页码:<span>{1}</span>/{2}</div> " ;
protected static readonly string navigateAjaxlinkFmt = " <li><a href=\"javascript:;\" οnclick=\"{0}('{1}');\" class=\"{3}\">{2}</a></li> " ;
protected static readonly string navigateDisableLinkFmt = " <li><a href=\"#\">{0}</a></li> " ;
protected static readonly string navigateGotoFmt = " <div class=\"fr\">转到第 <input type=\"text\" style=\"width: 40px;\" value=\"{1}\" οnblur=\"{0}(this.value);\"> 页</div> " ;
private PagedDataSource pagedDataSource = null ;
public FMPager()
{
pagedDataSource = new PagedDataSource();
}
public override void DataBind()
{
base .DataBind();
if ( string .IsNullOrEmpty(repeaterId))
{
return ;
}
Control repeater = FindRepeater(Page);
if (repeater == null || ! (repeater is Repeater))
{
return ;
}
ChildControlsCreated = false ;
Repeater finalRepeater = repeater as Repeater;
pagedDataSource.CurrentPageIndex = currentPageIndex;
pagedDataSource.PageSize = pageSize;
pagedDataSource.VirtualCount = recordCount;
pagedDataSource.DataSource = DataSource;
finalRepeater.DataSource = pagedDataSource;
finalRepeater.DataBind();
}
/// <summary>
/// 把数据内容传递到客户端
/// </summary>
protected override void Render(HtmlTextWriter output)
{
if (Site != null && Site.DesignMode)
{
CreateChildControls();
}
output.Write(OutputNavigate());
base .Render(output);
}
/// <summary>
/// 输出导航
/// </summary>
protected virtual string OutputNavigate()
{
// 总页码数
int pageCount = recordCount / pageSize;
if (recordCount % pageSize != 0 )
{
pageCount += 1 ;
}
if (currentPageIndex > pageCount)
{
currentPageIndex = pageCount;
}
StringBuilder sbNavigate = new StringBuilder();
// 输出跳转到
sbNavigate.AppendFormat(navigateGotoFmt, pagerJs, currentPageIndex);
// 获取第一页、上一页
sbNavigate.Append( " <ul> " );
if (currentPageIndex > 1 && pageCount > 1 )
{
sbNavigate.AppendFormat(navigateAjaxlinkFmt, pagerJs, 1 , " 第一页 " , "" );
sbNavigate.AppendFormat(navigateAjaxlinkFmt, pagerJs, currentPageIndex - 1 , " 上一页 " , "" );
}
else
{
sbNavigate.Append( string .Format(navigateDisableLinkFmt, " 第一页 " ));
sbNavigate.Append( string .Format(navigateDisableLinkFmt, " 上一页 " ));
}
// 获取数字页
int navigateCount = 10 ; // 每10页进行导航
int navigateTotal = pageCount / navigateCount; // 总计能生成多少个数字导航
int pageInNavigate = ((currentPageIndex - 1 ) / navigateCount) + 1 ; // 当前在第几个数字导航中
// 计算数字导航开始页序及结束页序
int startIndex = (pageInNavigate - 1 ) * navigateCount + 1 ; // 数字导航开始页序
int endIndex = startIndex + navigateCount - 1 ; // 数字导航结束页序
if (endIndex > pageCount)
{
endIndex = pageCount;
}
string currentPageClass = "" ;
for ( int i = startIndex; i <= endIndex; i ++ )
{
currentPageClass = "" ;
if (i == currentPageIndex)
{
currentPageClass = " pageactive " ;
}
sbNavigate.AppendFormat(navigateAjaxlinkFmt, pagerJs, i, i, currentPageClass);
}
// 获取下一页、最后页
if (currentPageIndex != pageCount && pageCount > 1 )
{
sbNavigate.AppendFormat(navigateAjaxlinkFmt, pagerJs, currentPageIndex + 1 , " 下一页 " , "" );
sbNavigate.AppendFormat(navigateAjaxlinkFmt, pagerJs, pageCount, " 最后页 " , "" );
}
else
{
sbNavigate.AppendFormat(navigateDisableLinkFmt, " 下一页 " );
sbNavigate.AppendFormat(navigateDisableLinkFmt, " 最后页 " );
}
sbNavigate.Append( " </ul> " );
// 输出总页数、当前页
sbNavigate.AppendFormat(navigatePageTotalFmt, recordCount, currentPageIndex, pageCount);
return string .Format(navigateClassFmt, sbNavigate.ToString());
}
/// <summary>
/// 查找输出Repeater
/// </summary>
private Control FindRepeater(Control ctrl)
{
Control retCtrl = ctrl.FindControl(repeaterId);
if (retCtrl != null )
{
return retCtrl;
}
foreach (Control childCtrl in Page.Controls)
{
retCtrl = childCtrl.FindControl(repeaterId);
if (retCtrl != null )
{
return retCtrl;
}
FindRepeater(retCtrl);
}
return null ;
}
/// <summary>
/// 绑定数据源
/// </summary>
public IEnumerable DataSource
{
get ;
set ;
}
[Description( " 当前页 " )]
public int CurrentPageIndex
{
get
{
currentPageIndex = HTMLHelper.QueryStringInt( " p " );
if (currentPageIndex <= 0 )
{
currentPageIndex = 1 ;
}
return currentPageIndex;
}
set
{
currentPageIndex = value;
}
}
private int currentPageIndex = 0 ;
[Description( " 分页控件ID " )]
public string RepeaterId
{
get
{
return repeaterId;
}
set
{
repeaterId = value;
}
}
private string repeaterId = "" ;
[Description( " 每页显示记录数 " )]
public int PageSize
{
get
{
return pageSize;
}
set
{
pageSize = value;
}
}
private int pageSize = 20 ;
[Description( " 总记录数 " )]
public int RecordCount
{
get
{
return recordCount;
}
set
{
recordCount = value;
}
}
private int recordCount = 0 ;
[Description( " JS分页函数 " )]
public string PagerJs
{
get
{
return pagerJs;
}
set
{
pagerJs = value;
}
}
private string pagerJs = " pagerObj.Page " ;
}
/// Repeater分页控件
/// </summary>
[ToolboxData( " <{0}:FMPager runat=\"server\" /> " )]
public class FMPager : WebControl, INamingContainer
{
protected static readonly string navigateClassFmt = " <div class=\"pageClass\">{0}</div> " ;
protected static readonly string navigatePageTotalFmt = " <div class=\"pagetotal\">总记录:<strong>{0}</strong> 页码:<span>{1}</span>/{2}</div> " ;
protected static readonly string navigateAjaxlinkFmt = " <li><a href=\"javascript:;\" οnclick=\"{0}('{1}');\" class=\"{3}\">{2}</a></li> " ;
protected static readonly string navigateDisableLinkFmt = " <li><a href=\"#\">{0}</a></li> " ;
protected static readonly string navigateGotoFmt = " <div class=\"fr\">转到第 <input type=\"text\" style=\"width: 40px;\" value=\"{1}\" οnblur=\"{0}(this.value);\"> 页</div> " ;
private PagedDataSource pagedDataSource = null ;
public FMPager()
{
pagedDataSource = new PagedDataSource();
}
public override void DataBind()
{
base .DataBind();
if ( string .IsNullOrEmpty(repeaterId))
{
return ;
}
Control repeater = FindRepeater(Page);
if (repeater == null || ! (repeater is Repeater))
{
return ;
}
ChildControlsCreated = false ;
Repeater finalRepeater = repeater as Repeater;
pagedDataSource.CurrentPageIndex = currentPageIndex;
pagedDataSource.PageSize = pageSize;
pagedDataSource.VirtualCount = recordCount;
pagedDataSource.DataSource = DataSource;
finalRepeater.DataSource = pagedDataSource;
finalRepeater.DataBind();
}
/// <summary>
/// 把数据内容传递到客户端
/// </summary>
protected override void Render(HtmlTextWriter output)
{
if (Site != null && Site.DesignMode)
{
CreateChildControls();
}
output.Write(OutputNavigate());
base .Render(output);
}
/// <summary>
/// 输出导航
/// </summary>
protected virtual string OutputNavigate()
{
// 总页码数
int pageCount = recordCount / pageSize;
if (recordCount % pageSize != 0 )
{
pageCount += 1 ;
}
if (currentPageIndex > pageCount)
{
currentPageIndex = pageCount;
}
StringBuilder sbNavigate = new StringBuilder();
// 输出跳转到
sbNavigate.AppendFormat(navigateGotoFmt, pagerJs, currentPageIndex);
// 获取第一页、上一页
sbNavigate.Append( " <ul> " );
if (currentPageIndex > 1 && pageCount > 1 )
{
sbNavigate.AppendFormat(navigateAjaxlinkFmt, pagerJs, 1 , " 第一页 " , "" );
sbNavigate.AppendFormat(navigateAjaxlinkFmt, pagerJs, currentPageIndex - 1 , " 上一页 " , "" );
}
else
{
sbNavigate.Append( string .Format(navigateDisableLinkFmt, " 第一页 " ));
sbNavigate.Append( string .Format(navigateDisableLinkFmt, " 上一页 " ));
}
// 获取数字页
int navigateCount = 10 ; // 每10页进行导航
int navigateTotal = pageCount / navigateCount; // 总计能生成多少个数字导航
int pageInNavigate = ((currentPageIndex - 1 ) / navigateCount) + 1 ; // 当前在第几个数字导航中
// 计算数字导航开始页序及结束页序
int startIndex = (pageInNavigate - 1 ) * navigateCount + 1 ; // 数字导航开始页序
int endIndex = startIndex + navigateCount - 1 ; // 数字导航结束页序
if (endIndex > pageCount)
{
endIndex = pageCount;
}
string currentPageClass = "" ;
for ( int i = startIndex; i <= endIndex; i ++ )
{
currentPageClass = "" ;
if (i == currentPageIndex)
{
currentPageClass = " pageactive " ;
}
sbNavigate.AppendFormat(navigateAjaxlinkFmt, pagerJs, i, i, currentPageClass);
}
// 获取下一页、最后页
if (currentPageIndex != pageCount && pageCount > 1 )
{
sbNavigate.AppendFormat(navigateAjaxlinkFmt, pagerJs, currentPageIndex + 1 , " 下一页 " , "" );
sbNavigate.AppendFormat(navigateAjaxlinkFmt, pagerJs, pageCount, " 最后页 " , "" );
}
else
{
sbNavigate.AppendFormat(navigateDisableLinkFmt, " 下一页 " );
sbNavigate.AppendFormat(navigateDisableLinkFmt, " 最后页 " );
}
sbNavigate.Append( " </ul> " );
// 输出总页数、当前页
sbNavigate.AppendFormat(navigatePageTotalFmt, recordCount, currentPageIndex, pageCount);
return string .Format(navigateClassFmt, sbNavigate.ToString());
}
/// <summary>
/// 查找输出Repeater
/// </summary>
private Control FindRepeater(Control ctrl)
{
Control retCtrl = ctrl.FindControl(repeaterId);
if (retCtrl != null )
{
return retCtrl;
}
foreach (Control childCtrl in Page.Controls)
{
retCtrl = childCtrl.FindControl(repeaterId);
if (retCtrl != null )
{
return retCtrl;
}
FindRepeater(retCtrl);
}
return null ;
}
/// <summary>
/// 绑定数据源
/// </summary>
public IEnumerable DataSource
{
get ;
set ;
}
[Description( " 当前页 " )]
public int CurrentPageIndex
{
get
{
currentPageIndex = HTMLHelper.QueryStringInt( " p " );
if (currentPageIndex <= 0 )
{
currentPageIndex = 1 ;
}
return currentPageIndex;
}
set
{
currentPageIndex = value;
}
}
private int currentPageIndex = 0 ;
[Description( " 分页控件ID " )]
public string RepeaterId
{
get
{
return repeaterId;
}
set
{
repeaterId = value;
}
}
private string repeaterId = "" ;
[Description( " 每页显示记录数 " )]
public int PageSize
{
get
{
return pageSize;
}
set
{
pageSize = value;
}
}
private int pageSize = 20 ;
[Description( " 总记录数 " )]
public int RecordCount
{
get
{
return recordCount;
}
set
{
recordCount = value;
}
}
private int recordCount = 0 ;
[Description( " JS分页函数 " )]
public string PagerJs
{
get
{
return pagerJs;
}
set
{
pagerJs = value;
}
}
private string pagerJs = " pagerObj.Page " ;
}
定义一个输出控件,继承自FMPager,用于输出具体的分页的内容:
View Code
///
<summary>
/// 存储过程分页
/// </summary>
public class ProcPager : FMPager
{
protected override void OnLoad(EventArgs e)
{
base .OnLoad(e);
FM.Business.ProcPager inf = new Business.ProcPager();
int recordCount = 0 ;
DataSet ds = inf.GetProcList( " TEST " , " ID, NAME, VAL " , "" , " ID " , this .CurrentPageIndex, this .PageSize, ref recordCount);
this .RecordCount = recordCount;
this .DataSource = ds.Tables[ 0 ].DefaultView;
base .DataBind();
}
}
/// 存储过程分页
/// </summary>
public class ProcPager : FMPager
{
protected override void OnLoad(EventArgs e)
{
base .OnLoad(e);
FM.Business.ProcPager inf = new Business.ProcPager();
int recordCount = 0 ;
DataSet ds = inf.GetProcList( " TEST " , " ID, NAME, VAL " , "" , " ID " , this .CurrentPageIndex, this .PageSize, ref recordCount);
this .RecordCount = recordCount;
this .DataSource = ds.Tables[ 0 ].DefaultView;
base .DataBind();
}
}
在专用ASPX页中调用,全部内容如下,没有HTML开始结束标识,只有输出内容:
View Code
<%
@ Page Language
=
"
C#
"
AutoEventWireup
=
"
true
"
CodeFile
=
"
ProcPager.aspx.cs
"
Inherits
=
"
AjaxHandler_ProcPager
"
%>
< asp:Repeater ID = " rpList " runat = " server " >
< HeaderTemplate >
< table class = " tb1 " cellspacing = " 2 " >
< tr class = " tr_bg " >
< td style = " width: 80%; " > 名称 </ td >
< td > 值 </ td >
</ tr >
</ HeaderTemplate >
< ItemTemplate >
< tr class = " tr_bg2 " >
< td ><% # Eval( " NAME " ) %></ td >
< td ><% # Eval( " VAL " ) %></ td >
</ tr >
</ ItemTemplate >
< FooterTemplate >
</ table >
</ FooterTemplate >
</ asp:Repeater >
< ctrl:ProcPager ID = " pagerTest " RepeaterId = " rpList " PageSize = " 2 " runat = " server " />
< asp:Repeater ID = " rpList " runat = " server " >
< HeaderTemplate >
< table class = " tb1 " cellspacing = " 2 " >
< tr class = " tr_bg " >
< td style = " width: 80%; " > 名称 </ td >
< td > 值 </ td >
</ tr >
</ HeaderTemplate >
< ItemTemplate >
< tr class = " tr_bg2 " >
< td ><% # Eval( " NAME " ) %></ td >
< td ><% # Eval( " VAL " ) %></ td >
</ tr >
</ ItemTemplate >
< FooterTemplate >
</ table >
</ FooterTemplate >
</ asp:Repeater >
< ctrl:ProcPager ID = " pagerTest " RepeaterId = " rpList " PageSize = " 2 " runat = " server " />
最后是JS分页函数:
View Code
/*
JS分页对象
参数:
containerId:载体的容器ID
url:分页数据地址
callbackFn:分页数据加载完成后的回调函数
*/
function PagerObj(containerId, url, callbackFn){
var obj = new Object;
obj.Page = page;
function page(currentIndex){
var finalUrl = url;
if (finalUrl.indexOf( ' ? ' ) == - 1 ){
finalUrl += ' ? ' ;
}
finalUrl += ' &p= ' + currentIndex;
finalUrl += ' &clearBuffer= ' + RandomKey(); // 消除浏览器缓存
var xmlhttp = XmlHttpRequest();
if ( ! xmlhttp){
alert( ' 创建xmlhttp对象异常! ' );
return ;
}
xmlhttp.open( ' POST ' , finalUrl, false );
xmlhttp.onreadystatechange = function (){
if (xmlhttp.readyState == 4 ){
document.getElementById(containerId).innerHTML = ' 数据加载中,请稍候... ' ;
if (xmlhttp.status == 200 ){
document.getElementById(containerId).innerHTML = xmlhttp.responseText;
if (callbackFn != null ){
callbackFn();
}
}
}
}
xmlhttp.send();
}
return obj;
}
JS分页对象
参数:
containerId:载体的容器ID
url:分页数据地址
callbackFn:分页数据加载完成后的回调函数
*/
function PagerObj(containerId, url, callbackFn){
var obj = new Object;
obj.Page = page;
function page(currentIndex){
var finalUrl = url;
if (finalUrl.indexOf( ' ? ' ) == - 1 ){
finalUrl += ' ? ' ;
}
finalUrl += ' &p= ' + currentIndex;
finalUrl += ' &clearBuffer= ' + RandomKey(); // 消除浏览器缓存
var xmlhttp = XmlHttpRequest();
if ( ! xmlhttp){
alert( ' 创建xmlhttp对象异常! ' );
return ;
}
xmlhttp.open( ' POST ' , finalUrl, false );
xmlhttp.onreadystatechange = function (){
if (xmlhttp.readyState == 4 ){
document.getElementById(containerId).innerHTML = ' 数据加载中,请稍候... ' ;
if (xmlhttp.status == 200 ){
document.getElementById(containerId).innerHTML = xmlhttp.responseText;
if (callbackFn != null ){
callbackFn();
}
}
}
}
xmlhttp.send();
}
return obj;
}
Web页面的输出:
View Code
<%
@ Page Language
=
"
C#
"
AutoEventWireup
=
"
true
"
CodeFile
=
"
Test.aspx.cs
"
Inherits
=
"
Test
"
%>
<! 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 runat ="server" >
< title ></ title >
</ head >
< body >
< form id ="form1" runat ="server" >
< div id ="divPager" style ="float: left; width: 100%;" > 分页数据的承载区域 </ div >
</ form >
< script type ="text/javascript" >
var pagerObj = null ;
window.onload = function (){
LoadInfo();
}
function LoadInfo(){
var url = ' AjaxHandler/ProcPager.aspx ' ;
pagerObj = new PagerObj( ' divPager ' , url, LoadInfoCallback);
pagerObj.Page( 1 );
}
function LoadInfoCallback(){
// alert('测试用回调函数');
}
// 创建XMLHttpRequest,不同浏览器调用的创建方法不一样
function XmlHttpRequest(){
var requestObj = null ;
if (window.XMLHttpRequest){
requestObj = new XMLHttpRequest();
} else {
try {
requestObj = new ActiveXObject( ' MSXML2.XMLHTTP.4.0 ' );
} catch (e){
try {
requestObj = new ActiveXObject( ' MSXML2.XMLHTTP.3.0 ' );
} catch (e){
try {
requestObj = new ActiveXObject( ' MSXML2.XMLHTTP.2.6 ' );
} catch (e){
try {
requestObj = new ActiveXObject( ' MSXML2.XMLHTTP ' );
} catch (e){
try {
requestObj = new ActiveXObject( ' Microsoft.XMLHTTP ' );
} catch (e){}
}
}
}
}
}
if (requestObj == null ){
alert( ' The browser does not surport XMLHTTP. ' );
}
return requestObj;
}
function PagerObj(containerId, url, callbackFn){
var obj = new Object;
obj.Page = page;
function page(currentIndex){
var finalUrl = url;
if (finalUrl.indexOf( ' ? ' ) == - 1 ){
finalUrl += ' ? ' ;
}
finalUrl += ' &p= ' + currentIndex;
finalUrl += ' &clearBuffer= ' + RandomKey(); // 消除浏览器缓存
var xmlhttp = XmlHttpRequest();
if ( ! xmlhttp){
alert( ' 创建xmlhttp对象异常! ' );
return ;
}
xmlhttp.open( ' POST ' , finalUrl, false );
xmlhttp.onreadystatechange = function (){
if (xmlhttp.readyState == 4 ){
document.getElementById(containerId).innerHTML = ' 数据加载中,请稍候... ' ;
if (xmlhttp.status == 200 ){
document.getElementById(containerId).innerHTML = xmlhttp.responseText;
if (callbackFn != null ){
callbackFn();
}
}
}
}
xmlhttp.send();
}
return obj;
}
// 生成随机数,用于消除页面缓存
function RandomKey(){
var hex = new Array( ' 0 ' , ' 1 ' , ' 2 ' , ' 3 ' , ' 4 ' , ' 5 ' , ' 6 ' , ' 7 ' , ' 8 ' , ' 9 ' , ' a ' , ' b ' , ' c ' , ' d ' , ' e ' , ' f ' );
var t = '' ;
for ( var i = 0 ; i < 32 ; i ++ ){
t += hex[Math.floor(Math.random() * 16 )];
}
return t.toUpperCase();
}
</ script >
</ body >
</ html >
<! 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 runat ="server" >
< title ></ title >
</ head >
< body >
< form id ="form1" runat ="server" >
< div id ="divPager" style ="float: left; width: 100%;" > 分页数据的承载区域 </ div >
</ form >
< script type ="text/javascript" >
var pagerObj = null ;
window.onload = function (){
LoadInfo();
}
function LoadInfo(){
var url = ' AjaxHandler/ProcPager.aspx ' ;
pagerObj = new PagerObj( ' divPager ' , url, LoadInfoCallback);
pagerObj.Page( 1 );
}
function LoadInfoCallback(){
// alert('测试用回调函数');
}
// 创建XMLHttpRequest,不同浏览器调用的创建方法不一样
function XmlHttpRequest(){
var requestObj = null ;
if (window.XMLHttpRequest){
requestObj = new XMLHttpRequest();
} else {
try {
requestObj = new ActiveXObject( ' MSXML2.XMLHTTP.4.0 ' );
} catch (e){
try {
requestObj = new ActiveXObject( ' MSXML2.XMLHTTP.3.0 ' );
} catch (e){
try {
requestObj = new ActiveXObject( ' MSXML2.XMLHTTP.2.6 ' );
} catch (e){
try {
requestObj = new ActiveXObject( ' MSXML2.XMLHTTP ' );
} catch (e){
try {
requestObj = new ActiveXObject( ' Microsoft.XMLHTTP ' );
} catch (e){}
}
}
}
}
}
if (requestObj == null ){
alert( ' The browser does not surport XMLHTTP. ' );
}
return requestObj;
}
function PagerObj(containerId, url, callbackFn){
var obj = new Object;
obj.Page = page;
function page(currentIndex){
var finalUrl = url;
if (finalUrl.indexOf( ' ? ' ) == - 1 ){
finalUrl += ' ? ' ;
}
finalUrl += ' &p= ' + currentIndex;
finalUrl += ' &clearBuffer= ' + RandomKey(); // 消除浏览器缓存
var xmlhttp = XmlHttpRequest();
if ( ! xmlhttp){
alert( ' 创建xmlhttp对象异常! ' );
return ;
}
xmlhttp.open( ' POST ' , finalUrl, false );
xmlhttp.onreadystatechange = function (){
if (xmlhttp.readyState == 4 ){
document.getElementById(containerId).innerHTML = ' 数据加载中,请稍候... ' ;
if (xmlhttp.status == 200 ){
document.getElementById(containerId).innerHTML = xmlhttp.responseText;
if (callbackFn != null ){
callbackFn();
}
}
}
}
xmlhttp.send();
}
return obj;
}
// 生成随机数,用于消除页面缓存
function RandomKey(){
var hex = new Array( ' 0 ' , ' 1 ' , ' 2 ' , ' 3 ' , ' 4 ' , ' 5 ' , ' 6 ' , ' 7 ' , ' 8 ' , ' 9 ' , ' a ' , ' b ' , ' c ' , ' d ' , ' e ' , ' f ' );
var t = '' ;
for ( var i = 0 ; i < 32 ; i ++ ){
t += hex[Math.floor(Math.random() * 16 )];
}
return t.toUpperCase();
}
</ script >
</ body >
</ html >
整个功能实施完毕,最后推荐使用jQuery,它封装了Ajax相关方法,我们不再需要自己实现XmlHttpRequest对象,只需利用jQuery进行异步请求即可,下面是利用jQuery实现的JS分页对象:
function
PagerObj(op){
var obj = new Object;
obj.Page = page;
var settings = $.extend({
containerId: ' divPager ' , // 容器编号
url: '' , // 分页请求URL地址
extendParams: '' , // URL地址扩展参数
callbackFn: null // 加载完毕后的回调函数
}, op);
function page(currentIndex){
var finalUrl = settings.url;
if (finalUrl.indexOf( ' ? ' ) == - 1 ){
finalUrl += ' ? ' ;
}
finalUrl += ' &p= ' + currentIndex;
finalUrl += ' &clearBuffer= ' + RandomKey(); // 消除浏览器缓存
$.ajax({
type: " POST " ,
url: finalUrl,
data: settings.extendParams,
success: function (html){
pageCallback(html);
}
});
}
function pageCallback(html){
$( ' # ' + settings.containerId).html(html);
if (settings.callbackFn != null ){
settings.callbackFn();
}
}
return obj;
}
var obj = new Object;
obj.Page = page;
var settings = $.extend({
containerId: ' divPager ' , // 容器编号
url: '' , // 分页请求URL地址
extendParams: '' , // URL地址扩展参数
callbackFn: null // 加载完毕后的回调函数
}, op);
function page(currentIndex){
var finalUrl = settings.url;
if (finalUrl.indexOf( ' ? ' ) == - 1 ){
finalUrl += ' ? ' ;
}
finalUrl += ' &p= ' + currentIndex;
finalUrl += ' &clearBuffer= ' + RandomKey(); // 消除浏览器缓存
$.ajax({
type: " POST " ,
url: finalUrl,
data: settings.extendParams,
success: function (html){
pageCallback(html);
}
});
}
function pageCallback(html){
$( ' # ' + settings.containerId).html(html);
if (settings.callbackFn != null ){
settings.callbackFn();
}
}
return obj;
}
调用方法:
function
LoadInfo(){
var url = ' AjaxHandler/ProcPager.aspx ' ;
pagerObj = new PagerObj({
url: url,
callbackFn: LoadInfoCallback
});
pagerObj.Page( 1 );
}
var url = ' AjaxHandler/ProcPager.aspx ' ;
pagerObj = new PagerObj({
url: url,
callbackFn: LoadInfoCallback
});
pagerObj.Page( 1 );
}
顺带一提,利用上面的JS分页对象可以实现同一页中的多个分页列表:
View Code
var
pagerObj
=
null
;
var pagerTestObj = null ;
$( function (){
LoadInfo();
LoadTestInfo();
})
function LoadInfo(){
var url = ' AjaxHandler/ProcPager.aspx ' ;
pagerObj = new PagerObj({
url: url
});
pagerObj.Page( 1 );
}
function LoadTestInfo(){
var url = ' AjaxHandler/TestPager.aspx ' ;
pagerTestObj = new PagerObj({
containerId: ' divTestPager ' ,
url: url
});
pagerTestObj.Page( 1 );
}
var pagerTestObj = null ;
$( function (){
LoadInfo();
LoadTestInfo();
})
function LoadInfo(){
var url = ' AjaxHandler/ProcPager.aspx ' ;
pagerObj = new PagerObj({
url: url
});
pagerObj.Page( 1 );
}
function LoadTestInfo(){
var url = ' AjaxHandler/TestPager.aspx ' ;
pagerTestObj = new PagerObj({
containerId: ' divTestPager ' ,
url: url
});
pagerTestObj.Page( 1 );
}
最终效果:
放出本文源码:
Pager_Demo.rar