最近开发一个前端图表模块,使用jQuery和Highchart开发,然后提供给其他人用,发现调用时要写太多代码,能不能一行搞定。之前开发过几个jQuery扩展,于是也做成jQuery扩展,调用时类似$(‘#chart’).warning(options)这样子,简洁了不少。
jQuery扩展有两种,一种是$(‘#element’).func(),使用了选择器,定义是:
(function($) {
//Plugin fucntions
$.fn.PluginName = function(options) {
// Plugin initial
}
})(jQuery);
将PluginName这个插件注册到$.fn上面,另外一种$.func(options),不绑定元素的,定义是:
(function($) {
//Plugin fucntions
$.PluginName = function(options) {
// Plugin initial
}
})(jQuery);
将PluginName直接挂在了$对象下面。
jQeury.extend方法可以用来扩展对象,也可以用来增加插件:
//$('#el').PluginName方式
jQuery.fn.extend({
PluginName: function(options) {
// Plugin initial
}
});
//对原有的PluginName插件再进一步扩展,也可用于升级插件而不修改原有代码
jQuery.fn.PluginName.extend({
doSomething: function(options) {
// Plugin extend
}
});
jQuery.extend(true, jQuery.fn.PluginName.prototype, {});
//$.PluginName方式
jQuery.extend({
PluginName: function(options) {
// Plugin initial
}
});
jQuery.PluginName.extend({
doSomething: function(options) {
// Plugin extend
}
});
以下是一个简单的jQuery插件模板,来自这里:
/*
* Project:
* Description:
* Author:
* License:
*/
// the semi-colon before function invocation is a safety net against concatenated
// scripts and/or other plugins which may not be closed properly.
;(function ( $, window, document, undefined ) {
// undefined is used here as the undefined global variable in ECMAScript 3 is
// mutable (ie. it can be changed by someone else). undefined isn't really being
// passed in so we can ensure the value of it is truly undefined. In ES5, undefined
// can no longer be modified.
// window is passed through as local variable rather than global
// as this (slightly) quickens the resolution process and can be more efficiently
// minified (especially when both are regularly referenced in your plugin).
// Create the defaults once
var pluginName = 'defaultPluginName',
defaults = {
propertyName: "value"
};
// The actual plugin constructor
function Plugin( element, options ) {
this.element = element;
// jQuery has an extend method which merges the contents of two or
// more objects, storing the result in the first object. The first object
// is generally empty as we don't want to alter the default options for
// future instances of the plugin
this.options = $.extend( {}, defaults, options) ;
this._defaults = defaults;
this._name = pluginName;
this.init();
}
Plugin.prototype.init = function () {
// Place initialization logic here
// You already have access to the DOM element and the options via the instance,
// e.g., this.element and this.options
};
// You don't need to change something below:
// A really lightweight plugin wrapper around the constructor,
// preventing against multiple instantiations and allowing any
// public function (ie. a function whose name doesn't start
// with an underscore) to be called via the jQuery plugin,
// e.g. $(element).defaultPluginName('functionName', arg1, arg2)
$.fn[pluginName] = function ( options ) {
var args = arguments;
// Is the first parameter an object (options), or was omitted,
// instantiate a new instance of the plugin.
if (options === undefined || typeof options === 'object') {
return this.each(function () {
// Only allow the plugin to be instantiated once,
// so we check that the element has no plugin instantiation yet
if (!$.data(this, 'plugin_' + pluginName)) {
// if it has no instance, create a new one,
// pass options to our plugin constructor,
// and store the plugin instance
// in the elements jQuery data object.
$.data(this, 'plugin_' + pluginName, new Plugin( this, options ));
}
});
// If the first parameter is a string and it doesn't start
// with an underscore or "contains" the `init`-function,
// treat this as a call to a public method.
} else if (typeof options === 'string' && options[0] !== '_' && options !== 'init') {
// Cache the method call
// to make it possible
// to return a value
var returns;
this.each(function () {
var instance = $.data(this, 'plugin_' + pluginName);
// Tests that there's already a plugin-instance
// and checks that the requested public method exists
if (instance instanceof Plugin && typeof instance[options] === 'function') {
// Call the method of our plugin instance,
// and pass it the supplied arguments.
returns = instance[options].apply( instance, Array.prototype.slice.call( args, 1 ) );
}
// Allow instances to be destroyed via the 'destroy' method
if (options === 'destroy') {
$.data(this, 'plugin_' + pluginName, null);
}
});
// If the earlier cached method
// gives a value back return the value,
// otherwise return this to preserve chainability.
return returns !== undefined ? returns : this;
}
};
}(jQuery, window, document));
根据这个就可以方便的开发jQuery插件了。
也可以使用jQuery.widget来开发一个插件,参考这里:
//新插件
$.widget( "custom.superDialog", {} );
//继承原有jQuery UI插件
$.widget( "custom.superDialog", $.ui.dialog, {} );
除此之外,也可以自己写插件/模块:
(function () {
// 将插件/模块定义在闭包私有空间里,加载时候就会立即执行,初始化
this.PluginName = function(options) {
}
PluginName.prototype.doSomething = function(options) {
}
}());
然后就可以调用了
var plugin = new PluginName(options);
plugin.doSomething();
也可以这样子:
var MODULE = (function (my) {
my.moduleMethod = function () {
// method override, has access to old through old_moduleMethod...
};
return my;
}(MODULE || {}));
#子模块,挂在MODULE这个对象/命名空间下面
MODULE.sub = (function () {
var my = {};
// ...
return my;
}());
模块多了就需要模块管理工具了,比如RequireJS:
//定义
define('myModule',
['foo', 'bar'],
// module definition function
// dependencies (foo and bar) are mapped to function parameters
function ( foo, bar ) {
// return a value that defines the module export
// (i.e the functionality we want to expose for consumption)
// create your module here
var myModule = {
doStuff:function(){
console.log('Yay! Stuff');
}
}
return myModule;
});
#使用
require(['app/myModule'],
function( myModule ){
// start the main module which in-turn
// loads other modules
var module = new myModule();
module.doStuff();
});
Javascript模块话加载可以参考这里。
参考链接:
JavaScript Module Pattern: In-Depth
Advanced Plugin Concepts
Learning JavaScript Design Patterns
jQuery Plugin Pattern
理解jquery的$.extend()、$.fn和$.fn.extend()
Making Use of jQuery UI’s Widget Factory
Building Your Own JavaScript Modal Plugin
Writing Modular JavaScript With AMD, CommonJS & ES Harmony
Javascript文件加载:LABjs和RequireJS
jQuery Boilerplate——流行的jQuery插件开发模板