2013年9月23日 星期一

無限瀑布捲軸實作教學 - Infinite Scroll with JQuery Plugin

       無限瀑布捲軸 (Infinite Scroll) 是類似 facebook 網站當 scroll bar 捲到底就會再載入後面內容的效果。因為內容太多了,為了呈現的效率,不讓使用者等太久才回應,所以先載入部份,就先呈現給使用者看。使用者有興趣往下捲,才將後面的 content 讀出來顯示。
       --> Demo <--
       要做到這樣的效果,可以參考 Paul Irish 的 infinite scroll jquery plugin,網頁需 include jquery infinite scroll 的 javacript file。下載 jquery.infinitescroll.min.js。        <script src="js/jquery-1.7.1.min.js" type="text/javascript"></script>
<script src="js/jquery.infinitescroll.min.js" type="text/javascript"></script>

       而 HTML 部份,需要一個 container 來放要無限延展的內容,infinite scroll plugin 會透過 ajax 方式將讀入的內容放到 container 的最後。另外還需要一個 element 當做參考點,也就是當使用者瀏覽到這個 element,就會被認為是讀到最底部,infinite scroll plugin 就去讀後續的內容,所以這個 element 要放在網頁最下面。 <div id="content">
<p class="item">One</p>
<p class="item">Two</p>
<p class="item">Three</p>
</div>

<a id="next" href="index2.html">next page?</a><!-- 放在最底部 --> 
       以上面的例子,content 就是 container,裡面放了 p,當使用者瀏覽到 next ,就認為捲到底了,就要再去 server 端讀後續的內容 (一堆 p),然後插在 content 的最後一個 p 之後。所以透過 infinite scroll plugin 設定如下:$('#content').infinitescroll({
navSelector : "#next:last",
nextSelector : "a#next:last",
itemSelector : "#content p",
dataType : 'html'
//path: function(index) {
// return "content?product=3&page=" + index;
//}
}, function(newElements, data, url){
//USE FOR PREPENDING
// $(newElements).css('background-color','#ffef00');
// $(this).prepend(newElements);
//
//END OF PREPENDING
// window.console && console.log('context: ',this);
// window.console && console.log('returned: ', newElements);
});
       瀏覽到 navSelector 指定的 element 時,則 infinite scroll plugin 自動透過 ajax 從 nextSelector 指定的 URL 載入內容 (也就是index2.html),放到最後一個 itemSelector 指定的位置之後。隨著捲軸往下捲,會自動載入 index3.html, index4.html, ...,直到讀不到東西為止。這邊有幾點注意:
       1. 通常取 content 的 URL 不會是 index2.html 這種格式,你可以使用例如:href="content?page=2",也是可以的!infinite scroll plugin 會自動帶成 content?page=3, content?page=4, ...,然後你的 server side 程式,就可以取 page 值,產生後面的內容回給前端 browser 做顯示。
       2. 如果你取 content 的 URL 又更複雜,則可在初始 inifinitescroll 時,多帶 path: 的屬性傳入一個 function,告訴 infinite scroll 如何為你產生取 content 的 URL。例如上面註解掉的 path 部份,下一頁的 URL 是 "content?product=3&page=" + index。
       3. infinitescroll(options, function)的第二個參數就空著吧,它應該是用來在插入前對內容做一些前置處理後,才被插入時用的。
       接下來,重點中的重點。如果你已經捲到沒 content 了,你又不要 reload 整個網頁,只想把 container 的 content 刪光,重新載入 content 部份。例如,你本來以日期排序那些 content,當 user 點了 rank 排序,你要清掉 content,重新以 rank 排序後,載入 content 中。那你的 infinite scroll plugin 應該會失效,你必須重新初始化 container,簡單講就是刪光了 content 的裡的 p 之後,container.infinitescroll(); 要再跑一次,但這次 initial 要多執行幾行,把 infinitescroll plugin reset。如下:/***** Reset Infinite Scroll Plugin *****/
$('#content').infinitescroll('binding','unbind');
$('#content').data('infinitescroll', null);
$(window).unbind('.infscr');

/***** 上面Reset過之後,才再初始化一次container *****/
$('#content').infinitescroll({
navSelector : "#next:last",
nextSelector : "a#next:last",
itemSelector : "#content p",
dataType : 'html'
//path: function(index) {
// return "content?product=3&page=" + index;
//}
}, function(newElements, data, url){
//USE FOR PREPENDING
// $(newElements).css('background-color','#ffef00');
// $(this).prepend(newElements);
//
//END OF PREPENDING
// window.console && console.log('context: ',this);
// window.console && console.log('returned: ', newElements);
});

       參考文章:
       1. http://www.infinite-scroll.com/
       2. https://github.com/paulirish/infinite-scroll/blob/master/test/index.html
       3. https://github.com/paulirish/infinite-scroll/blob/master/test/index2.html
       4. http://media02.hongkiat.com/infinite-page-scroll/demo/infinite-scroll/index.html
       5. http://www.powerhour.at/devblog/reset-jquery-infinitescroll-after-ajax-call/


2 則留言:

許志瑋 提到...

我沿著上列網址裡的教學文章去做了一個練習的網頁,可是發現並無法順利執行。
我練習的網頁:http://www.mejen.com.tw/backfish/jscroll.php
我的設定是讓jquery去讀取bq.php這支程式,而bq.php裡面只有一行指令,就是echo $_GET['page'];
所以如果按教學文章裡的說明,正常來說,畫面應該是會陸續echo出1,2,3,4,5.....
不過目前畫面只是出現loading...,不確定它是否有去執行bq.php,也不知道問題在哪?
請大大們幫我看看,謝謝

elvis wang 提到...

志瑋好~

http://www.mejen.com.tw/backfish/jscroll.php ,這個網址現在好像連不到。

另外,Google Chrome 瀏覽器有很棒的 javascript debug功能(Ctrl+Shift+J)。

開啟Debug功能,你可以搭配Console輸出與檢視Network頁籤的HTTP封包,看看是否plugin有為你送出你期望的 Request。

試看看囉~~