jQuery插件編寫學習+實例——無限滾動


  最近自己在搞一個網站,需要用到無限滾動分頁,想想工作兩年有余了,竟然都沒有寫過插件,實在慚愧,於是簡單學習了下jQuery的插件編寫,然后分享出來。

 

先說下基礎知識,基本上分為兩種,一種是對象級別的插件,另一種是全局級別的插件。對象級別的插件就像是實例方法,它是屬於實例對象的,而全局級別的相當於靜態方法,是屬於類的,調用起來自然也就不一樣,對於全局級別的插件我們自然是使用jQuery來調用,比如$.NPScrollLoad(....),對象級別的插件自然是應用與jQuery對象上了,比如:$("selector").NPScrollLoad(...)。這個不難理解吧。

對於$.NPScrollLoad()這種形式,我們要對jQuery進行擴展,怎么擴展呢,很簡單,就像給對象賦值一樣

方法1:

方法2:

這就是在博客園,發布博客界面測試的,F12打開開發者工具,切換到Console,先輸入運行"$",確認頁面引入了jQuery,然后擴展jQuery,一種方法是直接給屬性名賦值$.youname = function(){...},另一種方法是使用$.extend({yourname:function(){...}}),使用哪種看個人喜好。

 

對於$("selector").NPScrollLoad()這種方式,擴展就不是jQuery本身了,而是jQuery.fn:

方法1:

方法2:

和全局級別的插件方法區別就是擴展的時$.fn而不是$。

 

因為各式各樣的插件很多,屬性重名的概率很高,為了避免這樣那樣的問題,我們使用閉包來寫插件,從而使插件的變量和function和其他的不互相影響,這個我盡量簡化:

 1 ;(function($) {
 2     // jQuery擴展
 3     $.youname = function([args]) {
 4         // TODO
 5     };
 6     // 或者
 7     $.extend({
 8         youname : function() {
 9             // TODO
10         }
11     });
12     
13     // jQuery對象擴展
14     $.fn.youname = function([args]) {
15         // TODO
16     };
17     // 或者
18     $.fn.extend({
19         youname : function() {
20             // TODO
21         }
22     });
23 }) (jQuery);

 

為什么要這樣寫?看下面的例子你就明白了:

這個其實就相當於我們直接執行一個匿名函數,並且傳遞給他一個參數,比如上面的例子就是,我們定義了一個匿名函數用來alert傳進去的參數,然后我們給它傳遞"hello!",它就會馬上執行,把插件的相關方法寫到這里面並且引入這個js文件的話也就會在第一時間把我們的插件擴展到jQuery上,從而可以直接使用,並且可以保護我們的代碼不受外面代碼影響,也不會污染其他的代碼。為了防止以后壓縮代碼的時候出錯,所以最好在前后都加上一個分號";"。

 

為了讓我們的插件足夠通用,我們需要把一些配置留給用戶自己定義,通用的做法是使用一個對象來承載所有的設置項,並給他們默認值。

1 var defaults = {
2     msg1: "hello1",
3     msg2: "hello2"
4 }

然后我們給我們的插件函數加上參數:

 1 ;(function($) {
 2     var defaults = {
 3     msg1: "hello1",
 4     msg2: "hello2"
 5     };
 6 
 7     $.NPScrollLoad = function(options) {
 8         var opts = $.extend(defaults, options);
 9         alert(opts.msg1 + opts.msg2);
10     };
11 
12 }) (jQuery);

 

然后就可以調用了

$.NPScrollLoad({msg1 : "你好"});
$.NPScrollLoad({msg1 : "你好", msg2 : "呵呵"});
$.NPScrollLoad({msg2 : "......"});
$.NPScrollLoad();

沒有賦值的屬性會使用defaults里面定義的默認值,賦值的屬性則會覆蓋defaults中相應的屬性。

 

下面是我寫的插件代碼,代碼有些地方比較拙劣,懶得設計和修改了。。。

 1 /**
 2  * 無限滾動
 3  * 作者:Null Pointer
 4  */
 5  ;(function($) {
 6     $.NPScrollLoad = function(options) {
 7         // var opts = $.extend($.NPScrollLoad.defaults, options);
 8         $.NPScrollLoad.defaults = $.extend($.NPScrollLoad.defaults, options);
 9         return $(window).scroll(function() {
10             processor.process();
11         });
12     };
13 
14     var processor = {
15         timeoutId: null,
16         process: function () {
17             clearTimeout(this.timeoutId);
18             this.timeoutId = setTimeout(function () {
19                 loadData();
20             }, 400);
21         }
22     };
23 
24     /**
25      * 加載數據
26      */
27     function loadData() {
28         if (($(document).height() - ($(document).scrollTop() + $(window).height())) <= $.NPScrollLoad.defaults.offsetPixelToLoad) {
29             $(window).unbind("scroll");
30             $.NPScrollLoad.preLoad();
31             $.post(
32                 $.NPScrollLoad.defaults.url,
33                 { pageIndex : $.NPScrollLoad.defaults.pageIndex },
34                 function (data) {
35                     $.each(data, function (i, item) {
36                         $.NPScrollLoad.handleResult(item);
37                     });
38                     $.NPScrollLoad.afterLoad();
39                     $.NPScrollLoad.defaults.pageIndex++;
40                     if (data.length < $.NPScrollLoad.defaults.pageSize) {
41                         $.NPScrollLoad.noMoreData();
42                     } else if ($.NPScrollLoad.defaults.pageIndex == $.NPScrollLoad.defaults.maxPage) {
43                          $.NPScrollLoad.reachMaxPage();
44                     } else {
45                         $(window).bind("scroll", processor.process)
46                     }
47                 }
48             );
49         }
50     };
51 
52 
53     /**
54      * 處理
55      */
56     $.NPScrollLoad.handleResult = function(jsonItem) {
57 
58     };
59 
60     /**
61      * 加載之前
62      */
63     $.NPScrollLoad.preLoad = function() {
64         $("#loading").fadeIn();
65     };
66 
67     /**
68      * 加載之后
69      */
70     $.NPScrollLoad.afterLoad = function() {
71         $("#loading").fadeOut();
72     };
73 
74     /**
75      *  無更多數據
76      */
77     $.NPScrollLoad.noMoreData = function() {
78         $("#nomoreresult").fadeIn();
79     };
80 
81     /**
82      * 到達最大頁數
83      */
84     $.NPScrollLoad.reachMaxPage = function() {
85         $("#loadmore").show();
86     };
87 
88     $.NPScrollLoad.defaults = {
89         /* 距離底部距離(開始加載數據) */
90         offsetPixelToLoad : 100,
91         url : "",
92         pageSize : 10,
93         maxPage : 5,
94         pageIndex : 1
95     };
96 
97 })(jQuery);

 

 

代碼中有一部分是我之前沒有說到的細節:

1.我把defaults定義成$.NPScrollLoad.defaults這樣用戶可以在外部直接設置默認值,比如$.NPScrollLoad.defaults.url = "text.aspx";這樣就行了。

2.在(function($){})(jQuery)內部定義的function是私有的,只有此function內可以訪問,比如loadData就只可以在此匿名函數內部訪問。

3.我把部分function寫成jQuery的擴展,用戶就可以在外部訪問,或者自定義,比如$.NPScrollLoad.handleResult這樣就可以間接實現類似於函數重寫的功能,讓用戶自定義部分操作。

4.第九行我加了一個return,這里是為了延續jQuery的鏈式調用,比如$("selector").val("abc").attr("id", "aaa")。。。。因為jQuery的函數本身都是返回自身的,所以$(window).scroll()也會返回$(window),所以最后的return可以延續其鏈式調用特性,不過,因為我寫的是全局擴展,所以也就談不上鏈式調用了。。。這個對於對象擴展還是有一定重要性的。

5.定義processor對象是因為實時監聽scroll事件灰常消耗資源,沒滑過1px都會觸發事件,所以加個延遲時間,讓其一定時間內如果觸發的話就取消前一次事件。代碼應該不難理解。

下面是調用代碼:

1 <script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-1.10.2.min.js"></script>
2 <script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery.NPScrollLoad.1.0.js"></script>
3 <script type="text/javascript">
4 $(function() {
5     var contextPath = "${pageContext.request.contextPath}";
6     $.NPScrollLoad({url:contextPath + "/ajaxPage/home"});
7 });
8 </script>

 

 

本來還想排版,這么晚了,算了,睡覺了。

 

 


免責聲明!

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



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