ASP.NET仿新浪微博下拉加載更多數據瀑布流效果

    閒來無事,琢磨着寫點東西。貌似頁面下拉加載數據,瀑布流的效果很火,各個網站都能見到各式各樣的展示效果,原理大同小異。於是乎,決定自己寫一寫這個效果,希望能給比我還菜的菜鳥們一點參考價值。

    在開始之前,先把實現的基本原理說一下。當夜幕下拉到底部的時候,js可以判斷滾動條的位置,到達底部觸發js方法,執行jquery的ajax方法,向後臺一般處理程序夜幕ashx文件請求數據源,得到json格式的數據源。然後,遍歷json數據源,拼接一個li標籤,再填充到頁面上去。

    首先,我們來做個簡單的html頁面。頁面裏需要引入jquery庫,然後用jquery的ajax方法去請求後臺程序,也就是一般處理程序頁面。待會,我會在一般處理程序頁面ashx文件裏面寫方法,返回前端頁面所需要的新聞列表數據源。數據源的格式,我用的json格式。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>仿新浪微博下拉頁面底部加載更多</title>
    <style type="text/css">
        #main {
            margin: 10px auto;
            width: 990px;
        }

        #ListContent {
            color: white;
            position: relative;
        }

        #Listinfo {
            width: 850px;
            float: left;
            background-color: #071A37;
            position: relative;
            padding-bottom: 50px;
        }

            #Listinfo li {
                list-style: none;
                width: 800px;
                height: 40px;
                line-height: 40px;
                text-align: center;
                float: left;
            }

        #LoadingMsg {
            display: none;
            margin: 0 0;
            padding: 0 0;
            height: 25px;
            line-height: 25px;
            width: 800px;
            position: absolute;
            left: 48px;
            text-align: center;
            vertical-align: middle;
            bottom: 20px;
        }

            #LoadingMsg span {
                margin: 0 0;
                padding: 0 0;
                background: url(loading.gif) left center no-repeat;
                padding-left: 30px;
                height: 25px;
                line-height: 25px;
            }
    </style>
    <script type="text/javascript" src="jquery-1.8.2.js"></script>
    <script type="text/javascript">
        $(function () {
            var PageNum = 0;
            $(window).scroll(function () {
                var totalheight = parseFloat($(window).height()) + parseFloat($(window).scrollTop());//瀏覽器的高度加上滾動條的高度
                if ($(document).height() <= totalheight)//當文檔的高度小於或者等於總的高度的時候,開始動態加載數據
                {
                    $('#LoadingMsg').css('display', 'block');
                    var randcode = 1 + Math.round(Math.random() * 9999);
                    $.ajax({
                        type: "Get",
                        url: "Handler.ashx",
                        dataType: "json",
                        data: "PageNum=" + PageNum + "&randcode" + randcode,
                        success: function (data) {
                            $.each(data, function (i, item) {
                                if (item.Num == '-1') {
                                    $('#LoadingMsg').html('沒有更多數據了');
                                    $('#LoadingMsg').css('display', 'block');
                                }
                                else {
                                    $("#Listinfo").append("<li>" + item.Num + ".<font color='red'>" + item.Ntitle + "</font></li>");//加載數據
                                }
                            })
                            if (data.length > 0) {
                                PageNum++;
                            }
                            //$('#LoadingMsg').css('display', 'none');
                        },
                        error: function (XMLHttpRequest, textStatus, errorThrown) {
                            alert("程序錯誤,錯誤信息:" + errorThrown);
                        }
                    });
                }
            });
        })
    </script>
</head>
<body>
    <div id="main">
        <div id="ListContent">
            <ul id="Listinfo">
                <li>這裏是很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很的新聞標題</li>
                <li>這裏是很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很的新聞標題</li>
                <li>這裏是很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很的新聞標題</li>
                <li>這裏是很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很的新聞標題</li>
                <li>這裏是很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很的新聞標題</li>
                <li>這裏是很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很的新聞標題</li>
                <li>這裏是很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很的新聞標題</li>
                <li>這裏是很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很的新聞標題</li>
                <li>這裏是很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很的新聞標題</li>
                <li>這裏是很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很的新聞標題</li>
                <li>這裏是很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很的新聞標題</li>
                <li>這裏是很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很的新聞標題</li>
                <li>這裏是很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很的新聞標題</li>
                <li>這裏是很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很的新聞標題</li>
                <li>這裏是很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很的新聞標題</li>
                <li>這裏是很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很的新聞標題</li>
                <li>這裏是很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很的新聞標題</li>
                <li>這裏是很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很的新聞標題</li>
                <li>這裏是很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很的新聞標題</li>
                <li>這裏是很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很的新聞標題</li>
                <li>這裏是很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很的新聞標題</li>
                <li>這裏是很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很的新聞標題</li>
                <li>這裏是很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很的新聞標題</li>
                <li>這裏是很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很的新聞標題</li>
                <li>這裏是很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很的新聞標題</li>
                <li>這裏是很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很的新聞標題</li>
                <li>這裏是很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很的新聞標題</li>
                <li>這裏是很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很的新聞標題</li>
                <li>這裏是很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很的新聞標題</li>
                <li>這裏是很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很的新聞標題</li>
                <li>這裏是很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很的新聞標題</li>
                <li>這裏是很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很的新聞標題</li>
                <li>這裏是很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很的新聞標題</li>
                <li>這裏是很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很的新聞標題</li>
            </ul>
            <div style="clear: both"></div>
            <div id="LoadingMsg">
                <span>正在加載,請稍後...</span>
            </div>
        </div>
    </div>
</body>
</html>



    接下來,我們要創建數據庫,連接數據庫,讀取數據。這樣做太麻煩了,我直接用自定義的List數據來做演示了。我平時習慣爲數據庫每張表都創建一個實體類,以此隱射數據庫的表,字段。這裏我們創建一個NewsInfo的實體類,也就是通常的三層架構程序裏面的Model裏面的類。同時,我們自定義一些數據給他,這個作爲我們的數據源。真實開發環境下面,這個都是在DAL裏面去連接數據庫,讀取數據的。我這裏只是用作演示,希望你們懂的。我在實體類中定義了一個帶參數的名爲GetListByPn的方法。這個參數int類型的pn參數,你可以理解爲你下拉頁面的次數。比如當你第一次拉到頁面底部的時候,這個參數爲1,那我們就讀取前N條數據,當你第二次下拉到頁面底部的時候,這個參數爲2,那我們就讀取第N到2N條之間的N條數據,這個就是存儲過程分頁的原理。這個方法,我返回了一個類型是NewsInfo的List集合,這就是我們傳遞給前端頁面的數據源。    

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

/// <summary>
/// NewsInfo 的摘要說明
/// </summary>
public class NewsInfo
{
    public NewsInfo()
    {
        //
        // TODO: 在此處添加構造函數邏輯
        //
    }
    public int Num { get; set; }
    public string Ntitle { get; set; }

    /// <summary>
    /// 根據頁碼數獲取數據
    /// </summary>
    /// <param name="pn"></param>
    /// <returns></returns>
    public static List<NewsInfo> GetListByPn(int pn)
    {
        List<NewsInfo> NewList = new List<NewsInfo>();
        NewList.Add(new NewsInfo { Num = 0, Ntitle = "華米科技宣佈3500萬美元B輪融資 估值超3億美元" });
        NewList.Add(new NewsInfo { Num = 1, Ntitle = "淘汰CAPTCHA!谷歌推改良版CAPTCHA驗證" });
        NewList.Add(new NewsInfo { Num = 2, Ntitle = "朋友圈做微商爲何會如此遭人恨?買假貨 還刷屏" });
        NewList.Add(new NewsInfo { Num = 3, Ntitle = "社交化新聞聚合網站的未來發展趨勢" });
        NewList.Add(new NewsInfo { Num = 4, Ntitle = "雷軍未來3~5年間將砸10億美元投雲計算" });
        NewList.Add(new NewsInfo { Num = 5, Ntitle = "Oculus CEO:我是如何邂逅扎克伯格的" });
        NewList.Add(new NewsInfo { Num = 6, Ntitle = "實戰:股權衆籌行業融資流程介紹" });
        NewList.Add(new NewsInfo { Num = 7, Ntitle = "理財範應邀加入中關村互聯網金融行業協會" });
        NewList.Add(new NewsInfo { Num = 8, Ntitle = "P2P平臺的“羊毛”還能繼續擼嗎?沉迷易受傷" });
        NewList.Add(new NewsInfo { Num = 9, Ntitle = "美副國務卿:美中都是網絡***的受害者" });
        NewList.Add(new NewsInfo { Num = 10, Ntitle = "谷歌將推兒童版YouTube和Chrome瀏覽器" });
        NewList.Add(new NewsInfo { Num = 11, Ntitle = "高盛“免費”爲Uber打車融資數億美元" });
        NewList.Add(new NewsInfo { Num = 12, Ntitle = "觀察:支付寶A股掛牌還需邁過幾道檻" });
        NewList.Add(new NewsInfo { Num = 13, Ntitle = "優酷土豆劉德樂:多屏合一延伸視聽產業新邊界" });
        NewList.Add(new NewsInfo { Num = 14, Ntitle = "高盛“免費”爲Uber打車融資數億美元" });
        NewList.Add(new NewsInfo { Num = 15, Ntitle = "趣分期獲1億美金C輪融資 發力白領人羣" });
        NewList.Add(new NewsInfo { Num = 16, Ntitle = "優酷土豆劉德樂:多屏合一延伸視聽產業新邊界" });
        NewList.Add(new NewsInfo { Num = 17, Ntitle = "社交化新聞聚合網站的未來發展趨勢" });
        NewList.Add(new NewsInfo { Num = 18, Ntitle = "天天網董事長鞠傳國:美妝平臺還有上市空間" });
        NewList.Add(new NewsInfo { Num = 19, Ntitle = "百車寶 徐小平汽車領域投資第一單" });
        NewList.Add(new NewsInfo { Num = 20, Ntitle = "美副國務卿:美中都是網絡***的受害者" });
        NewList.Add(new NewsInfo { Num = 21, Ntitle = "視頻網站繼續發力硬件 盒子依然是香餑餑" });
        NewList.Add(new NewsInfo { Num = 22, Ntitle = "谷歌推出網絡機器人識別工具reCaptchas" });
        NewList.Add(new NewsInfo { Num = 23, Ntitle = "理財範應邀加入中關村互聯網金融行業協會" });
        NewList.Add(new NewsInfo { Num = 24, Ntitle = "《江南Style》視頻播放量爆表:谷歌被迫升級" });
        NewList.Add(new NewsInfo { Num = 25, Ntitle = "觀察:支付寶A股掛牌還需邁過幾道檻" });
        NewList.Add(new NewsInfo { Num = 26, Ntitle = "陌陌下週赴美上市 傍上阿里巴巴逆襲微信" });
        NewList.Add(new NewsInfo { Num = 27, Ntitle = "途牛同程封殺戰升級:驢媽媽半路聯手途牛" });
        NewList.Add(new NewsInfo { Num = 28, Ntitle = "互聯網時代更要尊重原創和夢想" });
        NewList.Add(new NewsInfo { Num = 29, Ntitle = "Skype前員工推出移動即時通訊應用Wire" });
        NewList.Add(new NewsInfo { Num = 30, Ntitle = "盤點:2014年Q3美國主要互聯網企業財報彙總" });
        NewList.Add(new NewsInfo { Num = 31, Ntitle = "盤點:西方社交媒體與社會資本研究綜述" });
        NewList.Add(new NewsInfo { Num = 32, Ntitle = "陌陌將在IPO同時向阿里巴巴與58同城增發新股" });
        NewList.Add(new NewsInfo { Num = 33, Ntitle = "從O2O閉環到推廣通 大衆點評移動廣告創新不斷" });
        NewList.Add(new NewsInfo { Num = 34, Ntitle = "佛山豪車相撞 瑪莎拉蒂衝上花基保時捷" });
        NewList.Add(new NewsInfo { Num = 35, Ntitle = "一汽馬自達高效保養服務提升品牌價值" });
        NewList.Add(new NewsInfo { Num = 36, Ntitle = "一汽大衆速騰後懸架斷裂事件持續 案例信息採集中" });
        NewList.Add(new NewsInfo { Num = 37, Ntitle = "居民自發組織“車管會” 保障權益化解停車難" });
        NewList.Add(new NewsInfo { Num = 38, Ntitle = "新能源車:強化充電設施准入門檻" });
        NewList.Add(new NewsInfo { Num = 39, Ntitle = "胡潤豪車報告引爭議 中國汽車文化尚未成熟" });
        NewList.Add(new NewsInfo { Num = 40, Ntitle = "725名速騰車主起訴一汽大衆 廠家舉行袖珍溝通會" });
        NewList.Add(new NewsInfo { Num = 41, Ntitle = "特斯拉PK比亞迪 誰是新能源車大贏家?" });
        NewList.Add(new NewsInfo { Num = 42, Ntitle = "深圳本田飛度享0.3萬優惠送5000大禮包" });
        NewList.Add(new NewsInfo { Num = 43, Ntitle = "國家放開電動車資質:誰將站上“風口”" });
        NewList.Add(new NewsInfo { Num = 44, Ntitle = "特斯拉能否打破中國式電動車發展困境?" });
        NewList.Add(new NewsInfo { Num = 45, Ntitle = "人民日報各抒己見:插電車爲何不插電" });
        NewList.Add(new NewsInfo { Num = 46, Ntitle = "評論:“停車場亂象”再證多頭管理之弊" });
        NewList.Add(new NewsInfo { Num = 47, Ntitle = "時事圖說:停車費給了誰" });
        NewList.Add(new NewsInfo { Num = 48, Ntitle = "評論:停車收費之亂不僅在於去向成謎" });
        NewList.Add(new NewsInfo { Num = 49, Ntitle = "評論:“鉅額停車費”到底去哪兒了?" });
        NewList.Add(new NewsInfo { Num = 50, Ntitle = "一汽轎車召回部分奔騰B50轎車" });
        NewList.Add(new NewsInfo { Num = 51, Ntitle = "我國進口車月均超11萬輛 SUV是絕對主力車型" });
        NewList.Add(new NewsInfo { Num = 52, Ntitle = "MPV 50%增速搶眼 家用化趨勢拉動商用車企跨界" });
        NewList.Add(new NewsInfo { Num = 53, Ntitle = "別克將推全新敞篷車型 或命名\"Velite\"" });
        NewList.Add(new NewsInfo { Num = 54, Ntitle = "[深圳]本田鋒範綜合優惠2.6萬元現車充足" });
        NewList.Add(new NewsInfo { Num = 55, Ntitle = "業內人士:汽車電商不會犧牲經銷商利益" });
        NewList.Add(new NewsInfo { Num = 56, Ntitle = "11月經銷商庫存指數再高企" });
        NewList.Add(new NewsInfo { Num = 57, Ntitle = "整車企業牽手租車公司 全產業鏈合作挖掘消費增長.." });
        NewList.Add(new NewsInfo { Num = 58, Ntitle = "用車小貼士:延長愛車壽命10妙招" });
        NewList.Add(new NewsInfo { Num = 59, Ntitle = "溫暖冬日 關懷延續昌河汽車續溫暖傳奇" });
        NewList.Add(new NewsInfo { Num = 60, Ntitle = "業主與業委會爲何“有仇”?法規監管存空白" });
        NewList.Add(new NewsInfo { Num = 61, Ntitle = "財苑訪談:降息利好房地產 一線城市房價仍然看漲" });
        NewList.Add(new NewsInfo { Num = 62, Ntitle = "王中丙在2014中國海洋經濟博覽會論壇上發表主旨.." });
        NewList.Add(new NewsInfo { Num = 63, Ntitle = "地板同質化需要業內企業共同作用" });
        NewList.Add(new NewsInfo { Num = 64, Ntitle = "房地產永久產權成爲現實後的9大猜想,你懂的" });
        NewList.Add(new NewsInfo { Num = 65, Ntitle = "世茂媒體行:世茂是如何將擅長的別墅做到了極致" });
        NewList.Add(new NewsInfo { Num = 66, Ntitle = "評論:小蠻腰鉅虧 買單的是你我" });
        NewList.Add(new NewsInfo { Num = 67, Ntitle = "“房屋永久產權“引發熱議 “老房子“反而更賣座" });
        NewList.Add(new NewsInfo { Num = 68, Ntitle = "電器起火爲何不能用水澆" });
        NewList.Add(new NewsInfo { Num = 69, Ntitle = "賈康:房地產稅立法將迎實質性安排" });
        NewList.Add(new NewsInfo { Num = 70, Ntitle = "公交減車減趟 廓清謠言更要讀懂民心【長城時評】" });
        NewList.Add(new NewsInfo { Num = 71, Ntitle = "評論:誰解“亮化工程畫樓”的風情?" });

        //IEnumerable<NewsInfo> query = from n in NewList where (n.Num >= 10 * pn && n.Num < 10 * (pn + 1)) select n;
        List<NewsInfo> ListQuery = (from n in NewList where (n.Num >= 10 * pn && n.Num < 10 * (pn + 1)) select n).ToList();
        return ListQuery;
    }
}

    現在,我們數據源已經有了,但是我們還沒有把數據源返回給前端頁面。怎麼返回呢?這裏用一般處理程序去做,就是後綴名爲ashx的文件。接着,我們新建一個一般處理程序頁面。在裏面接收前端頁面傳遞過來的參數pn,就是剛纔說到的你下拉頁面的次數。然後把List數據源反序列化爲Json字符串,返回給前端頁面。這裏我們需要定義一個方法去將List結構的數據反序列化爲Json格式的字符串。這個方法,我也是在百度上找的。而且,我在返回數據源給前端頁面時,讓線程暫停了5秒。因爲數據量比較少啊,一秒鐘都不需要就能加載出這10條數據來,但是你們做的時候可別寫這個暫停,這是說給某些“照抄黨”的,你懂了,就無視吧。

    

<%@ WebHandler Language="C#" Class="Handler" %>

using System;
using System.Web;
using System.Collections.Generic;
using System.Threading;
using System.Runtime.Serialization.Json;
using System.IO;
using System.Text;

public class Handler : IHttpHandler
{
    public void Proce***equest(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        int pn = 0;
        if (context.Request.QueryString["PageNum"] != null)
        {
            if (context.Request.QueryString["PageNum"].ToString().Trim() != string.Empty)
            {
                if (int.TryParse(context.Request.QueryString["PageNum"].ToString().Trim(), out pn))
                {
                    pn = int.Parse(context.Request.QueryString["PageNum"].ToString().Trim());
                }
            }
        }
        List<NewsInfo> ListQuery = NewsInfo.GetListByPn(pn);
        string ResultJson = "[{\"Num\":-1,\"Ntitle\":\"暫無數據\"}]";
        if (ListQuery.Count > 1)
        {
            ResultJson = Obj2Json<List<NewsInfo>>(ListQuery);
        }
        Thread.Sleep(5000);//因爲數據量比較少,這裏線程暫停5秒,讓頁面出現數據加載等待的效果
        context.Response.Write(ResultJson);
    }

    /// <summary>
    /// List轉Json
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="t"></param>
    /// <returns></returns>
    public static string Obj2Json<T>(T t)
    {
        try
        {
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(t.GetType());
            using (MemoryStream ms = new MemoryStream())
            {
                serializer.WriteObject(ms, t);
                return Encoding.UTF8.GetString(ms.ToArray());
            }
        }
        catch
        {
            return null;
        }
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}

    代碼就是這些了,現在運行看一下頁面的效果如何。





    好了,這個簡單的下拉加載更多數據的效果就算是做出來了。雖然沒有新浪微博那種的高大上,但是基本可以應付日常需要的效果。最重要的是,通過這個,讓大家明白基本原理吧。最後,附上程序源碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章