0

原始问题:

注意:下面的插件模式基于官方 jQuery 文档

我被卡住了...如何将以下插件模式转换为允许$.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

基于@JonJaques回复的代码:

;(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!你们这些人认真摇滚!

4

2 回答 2

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 替换为与您的配置没有相同键的对象,您的插件仍然可以从私有获取默认配置值多变的。

于 2012-07-03T07:41:28.337 回答
1

你到底对什么感到困惑?

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

opts(传入的 arg init)对应于传入插件的对象。

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

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

在里面init你想引用optionsvar,因为这个 var 代表你设置的默认值和用户指定的选项的组合。

这是否回答你的问题?

回应您的评论-您可以写

$.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然后您只需在插件代码中的其他任何地方引用该变量。

于 2012-07-03T08:08:12.213 回答