插件创作:如何允许$ .myPlugin.defaults.key ='value';?

时间:2012-07-03 07:31:09

标签: jquery plugins

原始问题:

注意:下面的插件模式基于the official jQuery docs

我被卡住了......如何将以下插件模式转换为允许$.hooplah.defaults.whoop = 'there it was';

;(function($) {

    var config = {};

    config.defaults = {
        foo   : 'bar',
        hey   : 'ho',
        whoop : 'there it is'
    };

    $.fn.hooplah = 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 on jQuery.hooplah.');
        }

    };

    var methods = {

        init: function(opts) {

            return this.each(function() {

                var options = $.extend({}, config.defaults, opts);

                // Stuff here...

            });

        }

    };

})(jQuery);

最理想的情况是,我想同时执行$('.foo').hooplah({ whoop: 'there is was' })$.hooplah.defaults.whoop = 'there it was';

任何提示/代码/链接将不胜感激。 :)

非常感谢您的帮助!


提议的解决方案#1

调用语法:$.pluginName.defaults

代码基于 @ AmithGeorge的回复:

;(function($) {

    var config = {};

    config.others = {
        blah : 'nah',
        cha  : 'right!',
        last : 'one'
    }

    config.defaults = {
        foo   : 'bar',
        hey   : 'ho',
        whoop : 'there it is'
    };

    $.hooplah = {};
    $.hooplah.defaults = config.defaults;
    $.hooplah.others   = config.others;

    $.fn.hooplah = 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 on jQuery.hooplah.');
        }

    };

    var methods = {

        init: function(opts) {

            return this.each(function() {

                var defaults = $.extend({}, config.defaults, config.others, $.hooplah.defaults, $.hooplah.others);

                // After some lines...

                var options = $.extend({}, defaults, opts);

                console.log(options);

                // Stuff here...

            });

        }

    };

})(jQuery);

HTML:

<ul id="nav><li>...</li></ul>

<script type="text/javascript">
    <!--

        $(document).ready(function() {

            $.hooplah.defaults.foo = 'foooooo';
            $.hooplah.defaults     = { whoop : 'what?' };
            $.hooplah.others.blah  = 'why?';
            $.hooplah.others       = { cha : 'ok' }
            $nav = $('#nav');
            $nav.hooplah({
                hey  : 'hey hey',
                last : 'first'
            });

        });

    //-->
</script>

之前输出:

blah     "nah"
cha      "right!"
foo      "bar"
hey      "ho"
last     "one"
whoop    "there it is"

输出之后:

blah     "why?"
cha      "ok"
foo      "foooooo"
hey      "hey hey"
last     "first"
whoop    "what?"

提议的解决方案#2

调用语法:$.fn.pluginName.defaults

基于 @JaJaques 回复的代码:

;(function($) {

    var config = {};

    config.others = {
        blah : 'nah',
        cha  : 'right!',
        last : 'one'
    }

    config.defaults = {
        foo   : 'bar',
        hey   : 'ho',
        whoop : 'there it is'
    };

    var methods = {

        init: function(opts) {

            return this.each(function() {

                var options = $.extend({}, config.defaults, config.others, $.fn.hooplah.defaults, $.fn.hooplah.others, opts);

                console.log(options);

                console.log(config.others.last); // Outputs "one".

                // Stuff here...

            });

        }

    };

    $.fn.hooplah = 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 on jQuery.hooplah.');
        }

    };

    $.fn.hooplah.defaults = config.defaults;

    $.fn.hooplah.others = config.others;

})(jQuery);

HTML:

<ul id="nav><li>...</li></ul>

<script type="text/javascript">
    <!--

        $(document).ready(function() {

            $nav = $('#nav');

            $.fn.hooplah.defaults.foo = 'foooooo';
            $.fn.hooplah.defaults     = { whoop : 'what?' };
            $.fn.hooplah.others.blah  = 'why?';
            $.fn.hooplah.others       = { cha : 'ok' }
            $nav.hooplah({
                hey  : 'hey hey',
                last : 'first'
            });

        });

    //-->
</script>

之前输出:

blah     "nah"
cha      "right!"
foo      "bar"
hey      "ho"
last     "one"
whoop    "there it is"

输出之后:

blah     "why?"
cha      "ok"
foo      "foooooo"
hey      "hey hey"
last     "first"
whoop    "what?"

真棒。 :)

如果上述代码示例可以改进和/或我忽略了某些内容,请告诉我。

谢谢@AmithGeorge和@JonJaques!你们认真地 ROCK!

2 个答案:

答案 0 :(得分:2)

为什么你不能这样做?

config.defaults = {
    foo   : 'bar',
    hey   : 'ho',
    whoop : 'there it is'
};

$.hooplah.config.defaults = config.defaults;

在你的init函数中,第一行是

var defaults = $.extend({}, config.defaults, $.hooplah.config.defaults);
// after some lines
var options = $.extend({}, defaults, opts);

我看到这样做的好处是,如果有人用一个没有与你的配置相同的密钥的对象替换$ .hooplah.config.defaults,你的插件仍然可以得到默认的配置值来自私人变量。

答案 1 :(得分:1)

你究竟对此感到困惑?

config.defaults定义默认值的地方。

opts(传递给init的arg)对应于传递到插件中的对象。

$('.foo').hooplah({
   whoop: 'there is was'
}

这会覆盖您的默认选项,但不会删除'foo'或'hey'。

init内部要引用options var,因为此var表示设置的默认值的组合,以及 user 指定。

这会回答你的问题吗?

回应你的评论 - 你可以写

$.fn.hooplah = function(method) {
  this.defaults = config.defaults;

然后将$ .fn.hooplah.defaults添加为扩展函数的第三个参数

var options = $.extend({}, config.defaults, $.fn.hooplah.defaults, opts);

config.defaults将是您对默认值的私人引用, $.fn.hooplah.defaults,将是一个公共可覆盖对象,用户可以在其中设置“全局”配置, 并且opts将是基于每次使用传入的对象。

然后,您只需在插件代码中的其他位置引用options变量。