如何使用jQuery插件公开公共属性?

如何使用jQuery插件公开公共属性?,jquery,plugins,methods,properties,public,Jquery,Plugins,Methods,Properties,Public,我正在使用jQuery构建一个小插件,但我希望它将一些数据公开为公共属性。例如: $(function () { $("#example1").myPlugin({ exampleData: 'bar' }); $("#example2").myPlugin({ exampleData: 'foo' }); $("#example3").myPlugin({

我正在使用jQuery构建一个小插件,但我希望它将一些数据公开为公共属性。例如:

$(function () {
        $("#example1").myPlugin({
            exampleData: 'bar'
        });
        $("#example2").myPlugin({
            exampleData: 'foo'
        });
        $("#example3").myPlugin({
            exampleData: 'too'
        });

        $('.click').click(function () {
            console.log($("#example1").myPlugin('getData'));
            console.log($("#example2").myPlugin('getData'));
            console.log($("#example3").myPlugin('getData'));
        });
    });
我希望控制台上的结果为:

'bar'
'foo'
'too'
我试图通过以下代码实现这一点:

(function ($) {
$.myPlugin = function (options) {
    $.myPlugin.settings = $.extend({
        exampleData: 'default value'
    }, options);
}

$.fn.myPlugin = function (methodOrOptions) {
    var methods = {
        getData: function () {
            return $(this).settings.exampleData;
        },
        init: function (options) {
            new $.myPlugin(options);
        }
    }

    if (methods[methodOrOptions]) {
        return methods[methodOrOptions].apply($(this), Array.prototype.slice.call(arguments, 1));
    } else if (typeof methodOrOptions === 'object' || !methodOrOptions) {
        return methods.init.apply($(this), arguments);
    } else {
        $.error('Method ' + methodOrOptions + ' does not exist on jQuery.myPlugin');
    }
};
})(jQuery);
但我得到“无法获取未定义或空引用的属性'exampleData'”


有人能帮我吗?

这条线路的主要问题是:

return $(this).settings.exampleData;
$(this)
返回jQuery集,而jQuery集没有
设置
属性

编写插件时要记住的一件主要事情是,您会被jQuery集调用,但您所做的一切都必须处理该集的子集。例如:

// Initialize on a set that includes *all* paragraphs
$("p").myPlugin();

// ...

// But now we do something with just the third paragraph; the
// plugin should expect that and store information on a per-
// element basis, not a per-set basis
$("p").eq(2).myPlugin("doSomething");
一种相当简单的方法是使用jQuery的
data
函数存储信息

值得一提的是,这里有一个包含“setData”和“getData”方法的基本插件示例。代码注释中的详细信息:

(function($) {
    "use strict";

    // Defaults
    var defaults = {
        // ...
    };

    // Methods
    var methods = {
        // (Note that `initialize` isn't on this list)
        getData:    getData,
        setData:    setData
    };

    // Utils
    var slice = Array.prototype.slice;

    // Expose the plugin
    $.fn.myPlugin = myPlugin;

    // Main entry point to plugin
    function myPlugin(arg) {
        var args = slice.call(arguments, 0);
        var method;
        var rv;

        // What are we doing?
        switch (typeof arg) {
            case "undefined":
            case "object":
                // Initializing
                rv = initialize.call(this, args);
                break;

            case "string":
                // Method, do we know it?
                method = methods[arg];
                if (!method) {
                    throw new Error("myPlugin: Unknown method '" + arg + "'");
                }
                args.shift(); // We've consumed the method name

                // Do it, return whatever it returns
                rv = method.call(this, args);
                break;

            default:
                throw new Error("myPlugin: Expected string or object as first argument if argument given.");
        }

        return rv;
    }

    // Initialize the plugin
    function initialize(args) {
        // Get the options
        var options = $.extend({}, defaults, args[0]);

        // Loop through, initializing the elements
        this.each(function() {
            // ...
            // (if appropriate here, you might detect whether you're being re-initialized
            // for the same element)
        });

        // Enable chaining
        return this;
    }

    // Get data
    function getData(args) {
        // "Get" operations only apply to the first element
        // Return the data; normally `args` wouldn't be used
        return this.first().data("myPlugin");
    }

    // Set data; "set" operations apply to all elements
    function setData(args) {
        this.data("myPlugin", args[0]);
        return this;
    }
})(jQuery);

这就是我所说的详尽的答案——非常感谢,这对我帮助很大。顺便问一下,我在问题中没有提到它,但是有没有办法将插件的使用限制为只使用唯一的元素?也就是说,只有当jQuery选择器类似于$('uniquelement'),而不是$('p')或$('someElementClass#anotherElementUniqueId.theElement')时,才允许插件工作的限制?如果出现这种情况,我如何检查并抛出错误?@T.J.克劳德:背景:我不是一个前端人员。。。两个快速问题:
varargs=slice.call(arguments,0)行中的
arguments
从何而来以及如何访问选项?我不明白你是如何从
var options=…
到插件中有这些选项的,如果这个变量不在其他地方,并且没有返回的话第三个问题(对不起)你能告诉我一个理解
($this.)函数中
初始化
函数中的每个()
的方向吗?我知道
($this)。each()
做什么-我只是不明白它在这方面会起什么作用context@PhillipHarrington:所有非箭头函数都有一个自动
参数
对象,其中包含调用它们时使用的参数:@PhillipHarrington:(重新编辑)您可以在
每个
回调中的代码中使用
选项
。Re
each
:调用插件时使用
this
引用调用它们的jQuery对象。因此
this.each
用于对jQuery对象中的每个元素进行操作。@T.J.Crowder-为什么我不直接说
this.options=$.extend({},默认值,args[0])
each()
函数是否必须进行切换才能查看参数是什么?