Javascript 如何扩展jquery插件';通过它的原型是什么样的公共方法?

Javascript 如何扩展jquery插件';通过它的原型是什么样的公共方法?,javascript,jquery,jquery-plugins,prototypal-inheritance,Javascript,Jquery,Jquery Plugins,Prototypal Inheritance,如何将插件的公共方法扩展到原型 例如,我的插件中有method1,我想通过它的.prototype添加另一个和更多。可能吗 var extensionMethods = { method2: function(){ return this; } }; $.fn.MyPlugin.prototype = extensionMethods; console.log($(".element").MyPlugin()); 结果, Object { Element={

如何将插件的公共方法扩展到原型

例如,我的插件中有method1,我想通过它的
.prototype
添加另一个和更多。可能吗

var extensionMethods = {
   method2: function(){
        return this;
    }
};

$.fn.MyPlugin.prototype = extensionMethods;

console.log($(".element").MyPlugin());
结果,

 Object { Element={...}, Options={...}, method1=function()}
理想情况下

 Object { Element={...}, Options={...}, method1=function(), method2=function(), method2function()}
我的插件样板

(function ($) {

    // Create the plugin name and defaults once
    var pluginName = 'MyPlugin';

    // Attach the plugin to jQuery namespace.
    $.fn[pluginName] = function(PublicOptions) {

        // Set private defaults.
        var Defaults = {
            param1:       'param1',
            param2:       'param2',
            onSuccess:    function(){}
        };

        // Do a deep copy of the options.
        var Options = $.extend(true, {}, Defaults, PublicOptions);

        // Define a functional object to hold the api.
        var PluginApi = function(Element, Options) {
            this.Element   = Element;
            this.Options   = Options;
        };

        // Define the public api and its public methods.
        PluginApi.prototype = {

            method1: function(PublicOptions) {

                // Process the options.
                var Options = $.extend(true, {}, this.Options, PublicOptions);
                return this.Options;
            }
        };

        //Create a new object of api.
        return new PluginApi(this, Options);
    };

})(jQuery);

有什么想法吗?

您不能将原型扩展到外部,因为您使用了隐藏对象插件API

您可以尝试将PluginApi存储在插件函数之外:

$[pluginName] = function(Element, Options) {
    this.Element   = Element;
    this.Options   = Options;
};
$[pluginName].prototype = {
    method1: function(PublicOptions) {
        // Process the options.
        var Options = $.extend(true, {}, this.Options, PublicOptions);
        return this.Options;
    }
};

$.fn[pluginName] = function(PublicOptions) {
    // Set private defaults.
    var Defaults = {
        param1:       'param1',
        param2:       'param2',
        onSuccess:    function(){}
    };

    // Do a deep copy of the options.
    var Options = $.extend(true, {}, Defaults, PublicOptions);

    return new $[pluginName](this, Options);
};
然后您可以扩展原型:

$.MyPlugin.prototype.method2 = function() {
    return this;
}

我认为在这种情况下,你能做的最好的结构根本不涉及原型。检查此插件库:

(function($) {

   // Set private defaults.
    var Defaults = {
        param1: 'param1',
        param2: 'param2',
        onSuccess: function() {}
    };

    // Define the public api and its public methods.
    var PluginApi = {

        extend: function(name, method) {
            PluginApi[name] = method;
            return this;
        },

        init: function(PublicOptions) {

            // Do a deep copy of the options.
            var Options = $.extend(true, {}, Defaults, PublicOptions);

            return this.each(function() {
                console.log('set up plugin logic', this.tagName);
            });
        },

        method1: function() {
            console.log('called: method1');
            return this;
        }
    };

    // Create the plugin name and defaults once
    var pluginName = 'MyPlugin';

    // Attach the plugin to jQuery namespace.
    $.fn[pluginName] = function(method) {

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

})(jQuery);
此插件结构允许您按预期链接方法:

$('h1').MyPlugin('method1').css('color', 'red');
如果需要使用不存在的方法,您可以这样做:

// Extend plugin "prototype" with method2 and use it
$('h1, h2').MyPlugin('extend', 'method2', function(prop, value) {
    return this.css(prop, value);
}).MyPlugin('method2', 'color', 'green');
检查下面演示中的用法示例

(函数($){
//设置私有默认值。
var默认值={
param1:'param1',
param2:'param2',
onSuccess:function(){}
};
//定义公共api及其公共方法。
变量PluginApi={
扩展:函数(名称、方法){
PluginApi[name]=方法;
归还这个;
},
初始化:函数(PublicOptions){
//对选项进行深度复制。
var Options=$.extend(true、{}、默认值、publicpoptions);
返回此值。每个(函数(){
console.log('setup plugin logic',this.tagName);
});
},
方法1:函数(){
log('called:method1');
归还这个;
}
};
//创建插件名称和默认值一次
var pluginName='MyPlugin';
//将插件附加到jQuery命名空间。
$.fn[pluginName]=函数(方法){
if(PluginApi[方法]){
返回PluginApi[method].apply(this,Array.prototype.slice.call(arguments,1));
} 
else if(typeof方法=='object'| |!方法){
返回PluginApi.init.apply(这是参数);
} 
否则{
$.error('Method'+Method+'不存在');
}
};
})(jQuery);
//调用existen method1:应使h1和h2为红色
$('h1,h2').MyPlugin('method1').css('color','red');
//调用不存在的方法2:应在控制台中引发错误
试一试{
$('h1,h2').MyPlugin('method2').css('color','green');
}
捕获(e){
//使用method2扩展“插件”原型
$('h1,h2').MyPlugin('extend','method2',function(prop,value){
返回这个.css(prop,value);
}).MyPlugin('method2','color','green');
}

H1

H2
根据您的结构(非常不幸,实际上,因为这不是jQuery插件),您只能通过返回的某个对象
$(“.element”).MyPlugin()访问
PluginApi.prototype
,因为
PluginApi
构造函数在IIFE中是本地的。但是这当然不是很好。我如何改变结构以允许这样做呢?大多数jquery插件返回
this
,以维护jquery的可链接性。为什么你如此热衷于在prototype上创建公共方法?@charlietfl你能提供一个链接性的例子吗?它包装了所有的插件代码并将其隔离(闭包),还为
$
提供了上下文,这样插件就不会在其他库使用的页面上中断
$
,谢谢你的回答。我可以问一下,在不依赖$(jQuery)的情况下,我如何做这个
$[pluginName]=函数(元素,选项){}
?还是根本不可能?@tealou我已经将PluginApi存储在$内,所以您可以在外部访问它,最好将员工存储在$.pluginName中。如果您不想将其存储在$s中,那么您可以使用window.MyPlugin代替。aww得到了它。我认为窗户是更好的选择。我不太喜欢依赖jquery。我认为,对基本结构的依赖越少越好!谢谢你的编辑。我可以问一下
调用什么(参数,1)是什么?为什么参数中有
1
?它将
参数
集合转换为参数数组,而不使用第一个参数。检查方法。