我正在使用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'未定义或空引用"
有人可以帮我吗?
答案 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);