• (转)jQuery插件编写学习+实例——无限滚动


    原文地址:http://www.cnblogs.com/nuller/p/3411627.html

      最近自己在搞一个网站,需要用到无限滚动分页,想想工作两年有余了,竟然都没有写过插件,实在惭愧,于是简单学习了下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>
    复制代码

    本来还想排版,这么晚了,算了,睡觉了。

  • 相关阅读:
    Vue.Draggable实现拖拽效果(快速使用)
    1.从面向过程到面向对象的过渡
    微信支付流程
    2.js原型的基本概念
    POST和GET请求的区别
    vue-router2.0
    vue列表渲染,以及鼠标点击改变样式的问题
    复杂数组结构的深拷贝
    高德地图将字符串地址转为经纬度的一个demo
    数组对象排序
  • 原文地址:https://www.cnblogs.com/fcsh820/p/3415299.html
Copyright © 2020-2023  润新知