如何扩展jQuery插件方法?

时间:2011-07-16 21:54:00

标签: jquery plugins

在下面的代码中,我试图扩展我的测试插件。我想为现有的插件添加一个新的方法定义。

(function($) {
    var settings = {
        bg: 'white'
    };

    var methods = {
        init: function(options) {
            options = $.extend({}, options, settings);
            return this.each(function () {
                $(this).data("test", options);
            });
        },
        whiten: function() {
            var options = this.data("test");
            this.css('background-color', options.bg);
        }
    };

    $.fn.test = function(method) {
        if (methods[method]) {
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === 'object' || !method) {
            return methods.init.apply(this, arguments);
        } else {
            $.error('Method ' + method + ' does not exist');
        } 
    }  

})(jQuery);

// New Method Definition
 var methods = {     
        newMethod: function(){
            alert('umut');   
      }
 };


// Extending test plugin with newMethod
$.fn.extend(true,$.fn.test, methods );

$(document).ready(function() {
    $('ul').test().css('background-color', 'wheat');
    $('#go').click(function() {
        $('ul').test("whiten");
        // Calling newMethod
        $('ul').test("newMethod");    
    });
});

但是我在firebug控制台上遇到了以下错误:

  

未捕获的异常:方法newMethod不存在

我如何扩展

var methods = {
}

阻止我的测试插件?

这是jsfiddle link

3 个答案:

答案 0 :(得分:3)

对于那些使用jQuery团队推荐的插件结构的人来说,由于只有一个函数添加到$ .fn对象,因此只添加一个公共函数,因此很难添加方法。所以,就我而言,我认为最好的解决方案是在扩展方法变量的插件中添加一个方法。这可以从插件外部访问,就像任何其他功能一样。示例:

(function($) {
    var settings = {
        bg: 'white'
    };

    var methods = {
        init: function(options) {
            options = $.extend({}, options, settings);
            return this.each(function () {
                $(this).data("test", options);
            });
        },
        whiten: function() {
            var options = this.data("test");
            this.css('background-color', options.bg);
        },
        extendMethods: function(newMethods) {
            $.extend(true, methods, newMethods);
            return $(this);
        }
    };

    $.fn.test = function(method) {
        if (methods[method]) {
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === 'object' || !method) {
            return methods.init.apply(this, arguments);
        } else {
            $.error('Method ' + method + ' does not exist');
        } 
    }  

})(jQuery);

瞧!然后你只需要这样称呼它:

$.fn.test('extendMethods',{...Methods object here...});

注意:我知道这需要您首先编辑插件代码,但是添加的内容并不多,并且在许多情况下可能是可行的。希望它可以帮助别人!

答案 1 :(得分:2)

编辑:我正在改变我的回答。这可能是更简单的解决方案,因为它需要更少的代码更改。添加methods作为插件的属性。在定义插件函数后添加此行:

$.fn.test.methods = methods;

这需要在定义插件的闭包内。您的其余代码应该正常工作,正如您已经在做的那样通过test扩展$.extend()

这是我的原始答案:

如果您希望能够以这种方式扩展插件,那么您的插件必须提供一种方法。您可以在methods中添加settings作为属性,然后在settings.methods方法中使用options.methodsinit进行深度扩展。

如果您打算将settings作为默认设置,并options覆盖设置,则在调用.extend()时,您的参数会被颠倒。反转你的参数,然后添加true作为第一个参数,使其成为一个深度扩展:

options = $.extend(true, {}, settings, options);

然后将您的方法放在settings

var settings = {
    bg: "white",
    methods: {
        init: function(options) {
            options = $.extend(true, {}, settings, options);
            ... // etc.
         },
         ...
    }
};

然后,不要通过$.extend()扩展插件的方法,而是在init电话中执行此操作:

$(".foo").test("init", { methods: methods });

答案 2 :(得分:0)

你不能因为methods只是函数的本地。如果您可以从外部访问它,则只能扩展它。