Sharing settings across methods in namespaced jQuery plugin
I'm writing a plugin and following the jQuery documentation's recommended practice http://docs.jquery.com/Plugins/Authoring when it comes to namespacing and multiple methods.
My init() takes care of merging default and custom settings using $.extend() however I can not figure out how to make those options available outside of the init() method. Say that call and initialize my plugin using
$("a").myplugin({debug:false});
how can I reference the debug property later when I call
$("a").myplugin("someMethod")?
A rough example is:
(function( $ ){
var methods = {
init: function(customSettings) {
var options = {
debug: true
}
return this.each(function () {
if (customSettings) {
$.extend(options, custom开发者_StackOverflow中文版Settings);
}
});
},
someMethod: function() {
if(options.debug) { // <-- How can I access options here?
// do something
}
}
}
})( jQuery );
$.fn.myplugin = 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.tbwaga');
}
};
I didn't look at your plugin template, but I wanted to share this jQuery plugin formatting... it adds a reverse reference to the DOM object in jQuery's stored data. This makes it very easy to access the plugin functions and/or variables even from outside of the plugin closure.
Here is a post describing the plugin structure in more detail.
So to access a function inside the plugin, you simply use the data object:
$('a').data('myplugin').function_name();
or even get a variable from the plugin settings
var height = $('a').data('myplugin').options.height;
But to answer your question, to make your options available to other functions inside the closure, just define the option variable outside of the init function:
(function( $ ){
var options, methods = {
init: function(customSettings) {
options = {
debug: true
}
Like fudgy wrote you may consider setting your defaults outside the init method. I tried following that same tutorial and came up with the following code combining settings and methods, but I ran into some other disadvantage.
(function( $ ){
var config, methods = {
init: function(customSettings) {
var config = {
debug: true
}
return this.each(function () {
if (customSettings) {
$.extend(config, customSettings);
}
});
},
someMethod: function(arg) {
if(options.debug) {
// do something
alert('debug ' + arg);
} else {
alert('no debug' + arg);
}
}
}
$.fn.myplugin = 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.myplugin' );
}
};
})( jQuery );
But when your call it like:
$('p.one').myplugin({ 'debug' : 'false' });
For the second paragraph debug is unfortunately still false.
$('p.two').myplugin('someMethod', 'hmm!');
I first need to init the paragraph with 'true' again to be able to debug it.
$('p.two').myplugin({ 'debug' : 'true' });
$('p.two').myplugin('someMethod', 'hmm!');
Did I oversee something in the tutorial?
精彩评论