關注電子商務網站開發-《JS+AJAX寫符合SEO規范的無刷新分頁》


無刷新分頁相信大家也看過不少,包括一些Jquery的分頁插件。之前做產品分頁的時候也下載研究過幾個,但是用現在的話說就是硬傷很多,不說代碼太多以及和自己數據庫很難對接,從SEO的角度考慮(必須要有有質量的鏈接),實在是就沒辦法用了。於是就決定自己寫了一個,一方面本人確實也稱不上高手,還是那句話,貼出來供大家參考,另一方面,文采很差,所以盡量少說話,多解釋代碼。

說明

無刷新的分頁主要分為三個步驟

步驟 A:數據庫分頁查詢

    方法A1

       方法A2

步驟B:后台分頁處理

     步驟B1

       步驟B2

步驟C:前台分頁調用。

          步驟C1

          步驟C2

慣例結尾會把實例附上。

 

 

步驟A :數據庫分頁查詢

這里提供兩種方法

方法A1:SQL SERVER自帶的分頁查詢語法

用我們這邊的產品數據庫做實例:查詢產品表Product中產品名(ProductName)中帶S的的第一頁數據,限制每頁個數為10,代碼:

 

declare @pageIndex int--頁數索引
declare @keyWord varchar(50)--搜索關鍵詞
declare @pageCount int--每頁數據個數
set @pageIndex=1
set @keyWord='S'
set @pageCount=10;
with Row as(SELECT row_number() over( order by addtime) as Num,AddTime,ProductName from Product where ProductName like '%'+@keyWord+'%' ) select top 10 * from Row where Num>(@pageIndex-1) * @pageCount  and  Num<= @pageIndex* @pageCount

 

結果返回一個DatatTable。這是一種比較簡單的方法,代碼也比較少,當然,支持的功能也有限,如果只是想簡單的實現分頁功能,可以考慮一下。

方法A2:SQL SERVER分頁存儲過程

此存儲過程是我在網上搜到的,具體地址我也記不清了,剛才在百度上搜了一下竟然沒搜到,在這里只能向作者說聲抱歉,貼一下你的代碼,如果有人能找到作者的原貼請留言發下地址,我會及時貼上去的。

View Code
CREATE PROC [dbo].[P_viewPage]

 

    @TableName VARCHAR(200),     --表名
    @FieldList VARCHAR(2000),    --顯示列名,如果是全部字段則為*
    @PrimaryKey VARCHAR(100),    --單一主鍵或唯一值鍵
    @Where VARCHAR(2000),        --查詢條件不含'where'字符,如id>10 and len(userid)>9
    @Order VARCHAR(1000),        --排序不含'order by'字符,如id asc,userid desc,必須指定asc或desc                                 
                                 --注意當@SortType=3時生效,記住一定要在最后加上主鍵,否則會讓你比較郁悶
    @SortType INT,               --排序規則1:正序asc 2:倒序desc 3:多列排序方法
    @RecorderCount INT,          --記錄總數0:會返回總記錄
    @PageSize INT,               --每頁輸出的記錄數
    @PageIndex INT,              --當前頁數
    @TotalCount INT OUTPUT,      --記返回總記錄
    @TotalPageCount INT OUTPUT   --返回總頁數
AS
    SET NOCOUNT ON

    IF ISNULL(@TotalCount,'') = '' SET @TotalCount = 0
    SET @Order = RTRIM(LTRIM(@Order))
    SET @PrimaryKey = RTRIM(LTRIM(@PrimaryKey))
    SET @FieldList = REPLACE(RTRIM(LTRIM(@FieldList)),' ','')

    WHILE CHARINDEX(', ',@Order) > 0 OR CHARINDEX(' ,',@Order) > 0
    BEGIN
        SET @Order = REPLACE(@Order,', ',',')
        SET @Order = REPLACE(@Order,' ,',',')    
    END

    IF ISNULL(@TableName,'') = '' OR ISNULL(@FieldList,'') = '' 
        OR ISNULL(@PrimaryKey,'') = ''
        OR @SortType < 1 OR @SortType >3
        OR @RecorderCount  < 0 OR @PageSize < 0 OR @PageIndex < 0        
    BEGIN 
        PRINT('ERR_00')       
        RETURN
    END    

    IF @SortType = 3
    BEGIN
        IF (UPPER(RIGHT(@Order,4))!=' ASC' AND UPPER(RIGHT(@Order,5))!=' DESC')
        BEGIN PRINT('ERR_02') RETURN END
    END

    DECLARE @new_where1 VARCHAR(1000)
    DECLARE @new_where2 VARCHAR(1000)
    DECLARE @new_order1 VARCHAR(1000)   
    DECLARE @new_order2 VARCHAR(1000)
    DECLARE @new_order3 VARCHAR(1000)
    DECLARE @Sql VARCHAR(8000)
    DECLARE @SqlCount NVARCHAR(4000)

    IF ISNULL(@where,'') = ''
        BEGIN
            SET @new_where1 = ' '
            SET @new_where2 = ' WHERE  '
        END
    ELSE
        BEGIN
            SET @new_where1 = ' WHERE ' + @where 
            SET @new_where2 = ' WHERE ' + @where + ' AND '
        END

    IF ISNULL(@order,'') = '' OR @SortType = 1  OR @SortType = 2 
        BEGIN
            IF @SortType = 1 
            BEGIN 
                SET @new_order1 = ' ORDER BY ' + @PrimaryKey + ' ASC'
                SET @new_order2 = ' ORDER BY ' + @PrimaryKey + ' DESC'
            END
            IF @SortType = 2 
            BEGIN 
                SET @new_order1 = ' ORDER BY ' + @PrimaryKey + ' DESC'
                SET @new_order2 = ' ORDER BY ' + @PrimaryKey + ' ASC'
            END
        END
    ELSE
        BEGIN
            SET @new_order1 = ' ORDER BY ' + @Order
        END

    IF @SortType = 3 AND  CHARINDEX(','+@PrimaryKey+' ',','+@Order)>0
        BEGIN
            SET @new_order1 = ' ORDER BY ' + @Order
            SET @new_order2 = @Order + ','            
            SET @new_order2 = REPLACE(REPLACE(@new_order2,'ASC,','{ASC},'),'DESC,','{DESC},')            
            SET @new_order2 = REPLACE(REPLACE(@new_order2,'{ASC},','DESC,'),'{DESC},','ASC,')
            SET @new_order2 = ' ORDER BY ' + SUBSTRING(@new_order2,1,LEN(@new_order2)-1)            
            IF @FieldList <> '*'
                BEGIN            
                    SET @new_order3 = REPLACE(REPLACE(@Order + ',','ASC,',','),'DESC,',',')                              
                    SET @FieldList = ',' + @FieldList                    
                    WHILE CHARINDEX(',',@new_order3)>0
                    BEGIN
                        IF CHARINDEX(SUBSTRING(','+@new_order3,1,CHARINDEX(',',@new_order3)),','+@FieldList+',')>0
                        BEGIN 
                        SET @FieldList = 
                            @FieldList + ',' + SUBSTRING(@new_order3,1,CHARINDEX(',',@new_order3))                        
                        END
                        SET @new_order3 = 
                        SUBSTRING(@new_order3,CHARINDEX(',',@new_order3)+1,LEN(@new_order3))
                    END
                    SET @FieldList = SUBSTRING(@FieldList,2,LEN(@FieldList))                     
                END            
        END

    SET @SqlCount = 'SELECT @TotalCount=COUNT(*),@TotalPageCount=CEILING((COUNT(*)+0.0)/'
                    + CAST(@PageSize AS VARCHAR)+') FROM ' + @TableName + @new_where1
    
    IF @RecorderCount  = 0
        BEGIN
             EXEC SP_EXECUTESQL @SqlCount,N'@TotalCount INT OUTPUT,@TotalPageCount INT OUTPUT',
                               @TotalCount OUTPUT,@TotalPageCount OUTPUT
        END
    ELSE
        BEGIN
             SELECT @TotalCount = @RecorderCount            
        END

    IF @PageIndex > CEILING((@TotalCount+0.0)/@PageSize)
        BEGIN
            SET @PageIndex =  CEILING((@TotalCount+0.0)/@PageSize)
        END

    IF @PageIndex = 1 OR @PageIndex >= CEILING((@TotalCount+0.0)/@PageSize)
        BEGIN
            IF @PageIndex = 1 --返回第一頁數據
                BEGIN
                    SET @Sql = 'SELECT TOP ' + STR(@PageSize) + ' ' + @FieldList + ' FROM ' 
                               + @TableName + @new_where1 + @new_order1
                END
            IF @PageIndex >= CEILING((@TotalCount+0.0)/@PageSize)  --返回最后一頁數據
                BEGIN
                    SET @Sql = 'SELECT TOP ' + STR(@PageSize) + ' ' + @FieldList + ' FROM (' 
                               + 'SELECT TOP ' + STR(ABS(@PageSize*@PageIndex-@TotalCount-@PageSize)) 
                               + ' ' + @FieldList + ' FROM '
                               + @TableName + @new_where1 + @new_order2 + ' ) AS TMP '
                               + @new_order1                    
                END        
        END    
    ELSE
        BEGIN
            IF @SortType = 1  --僅主鍵正序排序
                BEGIN
                    IF @PageIndex <= CEILING((@TotalCount+0.0)/@PageSize)/2  --正向檢索
                        BEGIN
                            SET @Sql = 'SELECT TOP ' + STR(@PageSize) + ' ' + @FieldList + ' FROM ' 
                                       + @TableName + @new_where2 + @PrimaryKey + ' > '
                                       + '(SELECT MAX(' + @PrimaryKey + ') FROM (SELECT TOP '
                                       + STR(@PageSize*(@PageIndex-1)) + ' ' + @PrimaryKey 
                                       + ' FROM ' + @TableName
                                       + @new_where1 + @new_order1 +' ) AS TMP) '+ @new_order1
                        END
                    ELSE  --反向檢索
                        BEGIN
                            SET @Sql = 'SELECT TOP ' + STR(@PageSize) + ' ' + @FieldList + ' FROM (' 
                                       + 'SELECT TOP ' + STR(@PageSize) + ' ' 
                                       + @FieldList + ' FROM '
                                       + @TableName + @new_where2 + @PrimaryKey + ' < '
                                       + '(SELECT MIN(' + @PrimaryKey + ') FROM (SELECT TOP '
                                       + STR(@TotalCount-@PageSize*@PageIndex) + ' ' + @PrimaryKey 
                                       + ' FROM ' + @TableName
                                       + @new_where1 + @new_order2 +' ) AS TMP) '+ @new_order2 
                                       + ' ) AS TMP ' + @new_order1
                        END
                END
            IF @SortType = 2  --僅主鍵反序排序
                BEGIN
                    IF @PageIndex <= CEILING((@TotalCount+0.0)/@PageSize)/2  --正向檢索
                        BEGIN
                            SET @Sql = 'SELECT TOP ' + STR(@PageSize) + ' ' + @FieldList + ' FROM ' 
                                       + @TableName + @new_where2 + @PrimaryKey + ' < '
                                       + '(SELECT MIN(' + @PrimaryKey + ') FROM (SELECT TOP '
                                       + STR(@PageSize*(@PageIndex-1)) + ' ' + @PrimaryKey 
                                       +' FROM '+ @TableName
                                       + @new_where1 + @new_order1 + ') AS TMP) '+ @new_order1                               
                        END 
                    ELSE  --反向檢索
                        BEGIN
                            SET @Sql = 'SELECT TOP ' + STR(@PageSize) + ' ' + @FieldList + ' FROM (' 
                                       + 'SELECT TOP ' + STR(@PageSize) + ' ' 
                                       + @FieldList + ' FROM '
                                       + @TableName + @new_where2 + @PrimaryKey + ' > '
                                       + '(SELECT MAX(' + @PrimaryKey + ') FROM (SELECT TOP '
                                       + STR(@TotalCount-@PageSize*@PageIndex) + ' ' + @PrimaryKey 
                                       + ' FROM ' + @TableName
                                       + @new_where1 + @new_order2 +' ) AS TMP) '+ @new_order2 
                                       + ' ) AS TMP ' + @new_order1
                        END  
                END                         
            IF @SortType = 3  --多列排序,必須包含主鍵,且放置最后,否則不處理
                BEGIN
                    IF CHARINDEX(',' + @PrimaryKey + ' ',',' + @Order) = 0 
                    BEGIN PRINT('ERR_02') RETURN END
                    IF @PageIndex <= CEILING((@TotalCount+0.0)/@PageSize)/2  --正向檢索
                        BEGIN
                            SET @Sql = 'SELECT TOP ' + STR(@PageSize) + ' ' + @FieldList + ' FROM ( '
                                       + 'SELECT TOP ' + STR(@PageSize) + ' ' + @FieldList + ' FROM ( '
                                       + ' SELECT TOP ' + STR(@PageSize*@PageIndex) + ' ' + @FieldList
                                       + ' FROM ' + @TableName + @new_where1 + @new_order1 + ' ) AS TMP '
                                       + @new_order2 + ' ) AS TMP ' + @new_order1    
                        END
                    ELSE  --反向檢索
                        BEGIN
                            SET @Sql = 'SELECT TOP ' + STR(@PageSize) + ' ' + @FieldList + ' FROM ( '  
                                       + 'SELECT TOP ' + STR(@PageSize) + ' ' + @FieldList + ' FROM ( '
                                       + ' SELECT TOP ' + STR(@TotalCount-@PageSize*@PageIndex+@PageSize) + ' ' + @FieldList
                                       + ' FROM ' + @TableName + @new_where1 + @new_order2 + ' ) AS TMP '
                                       + @new_order1 + ' ) AS TMP ' + @new_order1
                        END
                END
        END
    PRINT(@Sql)
EXEC(@Sql)

各個參數作者都做了解釋,只要給各個參數賦值,執行存儲過程就可以得到一個相應的Datatable。

 

 

步驟B:后台分頁處理

分頁處理方法也就是前台ajax調用的方法,有兩個參數,參數PageIndex  int類型,為當前頁數;參數key,搜索產品關鍵詞。方法返回List<String>類型,方法聲明代碼(.NET):

  [WebMethod]
    public static List<String> LoadProduct(int PageIndex, String key)
    {
    List<String> list = new List<String>();

    //..
    return list;
  }

 

實例中用的數據庫查詢方法是A2方法SQL SERVER分頁存儲過程,本人親測百萬條數據情況下執行這個存儲過程沒什么壓力。在分頁處理方法中聲明參數的代碼:

     string TableName = "VProducts";//表名
        string FieldList = "Pictures,ProductName,IDPlus,addtime";//字段集合
        string PrimaryKey = "IDPlus";//主鍵
        string Order = "IDPlus desc";//排序
        int SortType = 2;//排序規則 1:正序asc 2:倒序desc 3:多列排序方法
        int RecorderCount = 0;//字段集合
        int PageSize = 4;//每頁輸出的記錄數
        String where = "ProductName like '%" + key + "%'";
        SqlParameter[] paras = 
            {
                new SqlParameter("@TableName",TableName),
                new SqlParameter("@FieldList",FieldList),
                new SqlParameter("@TotalPageCount",SqlDbType.Int),
                new SqlParameter("@TotalCount",SqlDbType.Int),
                new SqlParameter("@PrimaryKey",PrimaryKey),
                new SqlParameter("@Where",where),
                new SqlParameter("@Order",Order),
                new SqlParameter("@SortType",SortType),
                new SqlParameter("@RecorderCount",RecorderCount),
                new SqlParameter("@PageSize",PageSize),
                new SqlParameter("@PageIndex",PageIndex)
            };
        paras[2].Direction = ParameterDirection.InputOutput;//設置
        paras[2].Value = 0;
        paras[3].Direction = ParameterDirection.InputOutput;//設置
        paras[3].Value = 0;
     DataTable  DT = DBHelper.GetDataTable("P_viewPage", paras);//執行存儲過程得到Datatable 

通過執行存儲過程得到一個DataTable。之后要進行兩個步驟操作。

步驟B1 遍歷這個datatable,然后填充到一個HTML模板里。

這個HTML模板就是顯示單條產品的HTML元素,如實例中把每個產品顯示在一個li里

String Temp = @"<li class='last'>
                            <div class='pic'>
                                <a href='javascript:void(0)'>
                                    <img width='160' src='{0}'  /></a>
                            </div>
                            <div class='name'>
                                <a href='javascript:void(0)'>{1}</a>
                            </div>
                        </li>";

然后就可以填充了,代碼:

     StringBuilder SB = new StringBuilder();//建議用StringBuilder

        int PageNum = Convert.ToInt32(paras[2].Value);//輸出參數 總頁數
        int ProductCount = Convert.ToInt32(paras[3].Value);//輸出參數 總個數
        if (DT != null && DT.Rows.Count != 0)
        {
            for (int i = 0; i < DT.Rows.Count; i++)
            {
             
                SB.AppendFormat(Temp, DT.Rows[i]["Pictures"].ToString(), DT.Rows[i]["ProductName"].ToString());
            }
        }


存儲過程還有兩個輸出參數,分別記錄總頁數和總個數。

步驟B2

 

步驟B1已經得到了該頁數的所有數據,步驟B2是關於頁數的操作,如圖:

這一塊的代碼要根據當前頁數及總頁數生產,並且為每頁分配一個可用連接,當在瀏覽器中輸入該連接,會加載該頁的產品。代碼:

View Code
StringBuilder SBPage = new StringBuilder();
        if (PageNum != 0)
        {
            #region 分頁顯示
            string path = System.Web.HttpContext.Current.Request.UrlReferrer + (key != "" ? "&" : "?") + "pageindex=";//判斷是否有參數key
            string strFirstTemp = "<li><a   onclick='return getList(1);'  href='" + path + "1'>首頁</a></li>";//拼接url
            string strLastTemp = "<li><a  onclick='return getList(" + (PageNum).ToString() + ");' href='" + path + (PageNum).ToString() + "' >尾頁</a></li>";
            string strFrontTemp = "<li><a onclick='return getList(" + (PageIndex - 1).ToString() + ");'  href='" + path + (PageIndex - 1).ToString() + "' >上一頁</a></li>";
            string strNextTemp = "<li><a onclick='return getList(" + (PageIndex + 1).ToString() + ");'  href='" + path + (PageIndex + 1).ToString() + "' >下一頁</a></li>";
            string strCurrentTemp = "<li><span >{0}</span></li>";
            string strPageTemp = "<li><a  onclick='return getList({0});' href='" + path + "{0}'>{0}</a></li>";
            //若頁數=1
            if (PageNum == 1)
            {
                SBPage.AppendFormat(strCurrentTemp, 1);
            }
            else//若頁數大於1
            {
                if (PageIndex == 1)//若當前頁=1
                {
                    SBPage.AppendFormat(strCurrentTemp, 1);
                    if (PageNum <= 10)//若總頁數小於等於10
                    {
                        for (int i = 2; i <= PageNum; i++)
                        {
                            SBPage.AppendFormat(strPageTemp, i);
                        }
                    }
                    else//若總頁數大於10
                    {
                        for (int i = 2; i <= 10; i++)
                        {
                            SBPage.AppendFormat(strPageTemp, i);
                        }
                    }
                    SBPage.Append(strNextTemp);
                    SBPage.Append(strLastTemp);
                }
                else if (PageIndex == PageNum)//若當前頁等於總頁數
                {
                    SBPage.Append(strFirstTemp);
                    SBPage.Append(strFrontTemp);
                    if (PageNum <= 10)//若總頁數小於等於10
                    {
                        for (int i = 1; i < PageNum; i++)
                        {
                            SBPage.AppendFormat(strPageTemp, i);
                        }
                    }
                    else//若總頁數大於10
                    {
                        for (int i = (PageNum - 9); i < PageNum; i++)
                        {
                            SBPage.AppendFormat(strPageTemp, i);
                        }
                    }
                    SBPage.AppendFormat(strCurrentTemp, PageNum);

                }
                else//若當前頁數不等於1且不等於總頁數
                {
                    if (1 < PageNum && PageNum <= 10)//若總頁數大於1小於等於10
                    {
                        SBPage.Append(strFirstTemp);
                        SBPage.Append(strFrontTemp);
                        for (int i = 1; i <= PageNum; i++)
                        {
                            if (PageIndex == i)
                            {
                                SBPage.AppendFormat(strCurrentTemp, i);
                            }
                            else
                            {
                                SBPage.AppendFormat(strPageTemp, i);
                            }
                        }
                        SBPage.Append(strNextTemp);
                        SBPage.Append(strLastTemp);

                    }
                    else//若總頁數大於10
                    {
                        if (1 < PageIndex && PageIndex <= 5)//若當前頁數大於1且小於等於5
                        {
                            SBPage.Append(strFirstTemp);
                            SBPage.Append(strFrontTemp);
                            for (int i = 1; i <= 10; i++)
                            {
                                if (PageIndex == i)
                                {
                                    SBPage.AppendFormat(strCurrentTemp, i);
                                }
                                else
                                {
                                    SBPage.AppendFormat(strPageTemp, i);
                                }
                            }
                            SBPage.Append(strNextTemp);
                            SBPage.Append(strLastTemp);

                        }
                        else//若當前頁數大於5
                        {
                            if (5 < PageIndex && PageIndex <= (PageNum - 5))//若當前頁數大於5且小於總頁數-5
                            {
                                SBPage.Append(strFirstTemp);
                                SBPage.Append(strFrontTemp);
                                for (int i = (PageIndex - 4); i <= (PageIndex + 5); i++)
                                {
                                    if (PageIndex == i)
                                    {
                                        SBPage.AppendFormat(strCurrentTemp, i);
                                    }
                                    else
                                    {
                                        SBPage.AppendFormat(strPageTemp, i);
                                    }
                                }
                                SBPage.Append(strNextTemp);
                                SBPage.Append(strLastTemp);

                            }
                            else//若當前頁數小於總頁數-5
                            {
                                SBPage.Append(strFirstTemp);
                                SBPage.Append(strFrontTemp);
                                for (int i = (PageNum - 9); i <= PageNum; i++)
                                {
                                    if (PageIndex == i)
                                    {
                                        SBPage.AppendFormat(strCurrentTemp, i);
                                    }
                                    else
                                    {
                                        SBPage.AppendFormat(strPageTemp, i);
                                    }
                                }
                                SBPage.Append(strNextTemp);
                                SBPage.Append(strLastTemp);
                            }
                        }
                    }
                }
            }

            #endregion
        }

最后把得到的各種數據添加到聲明的list里,並返回給前台JS處理

     

        list.Add(SB.ToString());

        list.Add(SBPage.ToString());

        list.Add(PageNum.ToString());

        list.Add(ProductCount.ToString());

     return list;

 

步驟C:前台分頁調用

 

同步步驟B2中的代碼已經看到返回的HTML元素中已經有了onclick事件,調用的是前台方法getList

 

我們來看看這個方法的代碼:

function getList(pageIndex) {
            $.ajax({
                type: "POST",
                url: "/cnblog/ajax.aspx/LoadProduct",
                data: "{'PageIndex':'" + pageindex + "','key':'" + decodeURIComponent($.request("key")) + "'}", //搜索關鍵字,如果沒有則為空
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: function (result) {
                    $(".productslist").html(result.d[0]);
                    $(".paginator").html(result.d[1]);
                    $(".pageCount").html(result.d[2]);
                    $(".productCount").html(result.d[3]);
                },
                error: function (result) {

                }
            });
            return false;//一定要加return false。在ie里一個超鏈接有onclick事件也有href屬性,如果不加return false 點擊的時候會觸發事件后再跳轉
        }

參數為pageIndex ,既頁數 ,所以當點擊返回的頁數連接時會調用這個方法,並且把頁數及搜索關鍵詞傳過去,傳過去之后得到的結果即為步驟B中LoadProduct方法的返回值。

我們來看看效果吧!

注意截圖上的文字解釋:

 

 

 

 

演示地址

演示地址

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM