php无刷新分页,无刷新分页

无刷新,利用客户端的XMLHttpRequest对象发起请求到服务器,服务器响应后发回数据再由客户端进行接收,由于XMLHttpRequest对象发起的请求与响应是异步方式,而不是产生中断,因而其数据处理过程能在页面中呈现出无刷新的效果。 进一步了解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请求: 无刷新分页php无刷新分页无刷新分页php无刷新分页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(); }

看看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 _disibledevent=>/// /// DataTable分页 /// 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 /// /// Repeater分页控件 /// [ToolboxData("<{0}:FMPager runat=\"server\" />")] public class FMPager : WebControl, INamingContainer { protected static readonly string navigateClassFmt = "{0}
"; protected static readonly string navigatePageTotalFmt = "总记录:{0}&nbsp;&nbsp;&nbsp;页码:{1}/{2}
"; protected static readonly string navigateAjaxlinkFmt = "
  • {2}
  • "; protected static readonly string navigateDisableLinkFmt = "
  • {0}
  • "; protected static readonly string navigateGotoFmt = "转到第&nbsp;&nbsp;页
    "; 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(); } /// /// 把数据内容传递到客户端 /// protected override void Render(HtmlTextWriter output) { if (Site != null && Site.DesignMode) { CreateChildControls(); } output.Write(OutputNavigate()); base.Render(output); } /// /// 输出导航 /// 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("
      "); 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("
    "); //输出总页数、当前页 sbNavigate.AppendFormat(navigatePageTotalFmt, recordCount, currentPageIndex, pageCount); return string.Format(navigateClassFmt, sbNavigate.ToString()); } /// /// 查找输出Repeater /// 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; } /// /// 绑定数据源 /// 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 /// /// 存储过程分页 /// public class ProcPager : FMPager { protected override void _disibledevent=>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" %>
    名称
    <%# Eval("NAME") %> <%# Eval("VAL") %>


    最后是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; }

    Web页面的输出: View Code <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Test.aspx.cs" Inherits="Test" %>
    分页数据的承载区域


    整个功能实施完毕,最后推荐使用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; }
    调用方法: function LoadInfo(){ 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); }

    最终效果: 无刷新分页php无刷新分页
    Tags:  无刷新 ajax无刷新 无分页文件 php无刷新分页

    延伸阅读

    最新评论

    发表评论