How can I emulate the Jquery UI API?
I've written basic jQuery plugins before, but I'm struggling to get my head around something more complex. I'm looking to emulate the API of jQuery UI, which works like this:
$('#mydiv').sortable({name: 'value'}); // constructor, options
$('#mydiv').sortable("serialize"); // call a method, with existing options
$('#mydiv').sortable('option', 'axis', 'x'); // get an existing option
I've tried the following:
(function($){
$.fn.myPlugin = function(cmd){
var config = {
default: 'defaultVal'
};
if(typeof cmd === 'object'){
$.extend(config, cmd);
}
function _foo(){
console.log(config.default);
}
if(cmd==='foo'){
return _foo();
}
this.each(function(){
// do d开发者_如何学Goefault stuff
});
}
})(jQuery);
$('#myElement').myPlugin({default: 'newVal'});
$('#myElement').myPlugin('foo');
What I would like to see here is 'newval' being logged, but I'm seeing 'defaultVal' instead; the plugin is being called and started from scratch every time I call .myPlugin() on the element.
I've also tried using _foo.call(this) and some other variants. No joy.
In a way, I understand why this is happening, but I know that it must be possible to do it the same way as jQuery UI. I just can't see how!
(I appreciate that jQuery UI uses the widget factory to handle all of this, but I don't want to make that a requirement for the plugin.)
Perhaps what you want is this...
(function($){
var config = {
default: 'defaultVal'
};
$.fn.myPlugin = function(cmd){
if(typeof cmd === 'object'){
$.extend(config, cmd);
}
function _foo(){
console.log(config.default);
}
if(cmd==='foo'){
return _foo();
}
this.each(function(){
// do default stuff
});
}
})(jQuery);
$('#myElement').myPlugin({default: 'newVal'});
$('#myElement').myPlugin('foo');
Move the config
variable outside the myPlugin
function. This change will cause config
to be initialized only once: when your plugin function is created.
You're declaring config during the function call rather than as a closure used by it. Try this:
(function($){
var config = {
default: 'defaultVal'
};
$.fn.myPlugin = function(cmd){
if(typeof cmd === 'object'){
$.extend(config, cmd);
}
function _foo(){
console.log(config.default);
}
if(cmd==='foo'){
return _foo();
}
this.each(function(){
// do default stuff
});
}
})(jQuery);
$('#myElement').myPlugin({default: 'newVal'});
$('#myElement').myPlugin('foo');
In addition, you could look into the jQuery data API for caching data, especially if you aren't going to have just one instance per page.
精彩评论