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

时间:2014-08-16 19:08:26

标签: jquery plugins methods properties public

我正在使用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);

但我得到了#34;无法获得财产' exampleData'未定义或空引用"

有人可以帮我吗?

1 个答案:

答案 0 :(得分:3)

主要问题在于这一行:

return $(this).settings.exampleData;

$(this)返回一个jQuery集,jQuery集没有settings属性。

编写插件时要记住的一个主要问题是,您使用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);

Live Example