带有选项和可访问方法的jQuery插件的模板?

我想构建一个带有可访问方法和选项的插件,这适用于复杂的插件。 我需要在插件外部访问这些方法,因为如果有人向DOM广告,则需要更新(因此我们不需要再次运行完整的插件)。

我在过去看到有插件可以这样做,但我找不到它们,所以我不能看看它们。 我还是javascript的新手,所以任何帮助都会很好。

如果我们仍然可以全局覆盖选项,那将是很好的。

我想如何使用插件:

// options $('#someid').myplugin({name: 'hello world'}); // methods(would be nice if we can use this) $('#someid').myplugin('update'); 

//我的旧插件包装器

 ;(function($, window, document, undefined){ $.fn.pluginmyPlugin = function(options) { options = $.extend({}, $.fn.pluginmyPlugin.options, options); return this.each(function() { var obj = $(this); // the code }); }; /** * Default settings(dont change). * You can globally override these options * by using $.fn.pluginName.key = 'value'; **/ $.fn.pluginmyPlugin.options = { name: '', ... }; })(jQuery, window, document); 

更新

所以在查看了jQuery文档后,我构建了以下代码,请告诉我代码是否有问题,如果可以更好地构建…

 ;(function($, window, document, undefined){ var methods = { init : function( options ) { options = $.extend({}, $.fn.pluginmyPlugin.options, options); return this.each(function(){ alert('yes i am the main code') }); }, update : function( ) { alert('updated') } }; $.fn.pluginmyPlugin = 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 this plugin' ); } }; /** * Default settings(dont change). * You can globally override these options * by using $.fn.pluginName.key = 'value'; **/ $.fn.pluginmyPlugin.options = { name: 'john doe', //.... }; })(jQuery, window, document); 

替代:

 var Plugin = function($self, options) { this.$self = $self; this.options = $.extend({}, $.fn.plugin.defaults, options); }; Plugin.prototype.display = function(){ console.debug("Plugin.display"); }; Plugin.prototype.update = function() { console.debug("Plugin.update"); }; $.fn.plugin = function(option) { var options = typeof option == "object" && option; return this.each(function() { var $this = $(this); var $plugin = $this.data("plugin"); if(!$plugin) { $plugin = new Plugin($this, options); $this.data("plugin", $plugin); } if (typeof option == 'string') { $plugin[option](); } else { $plugin.display(); } }); }; $.fn.plugin.defaults = { propname: "propdefault" }; 

用法:

 $("span").plugin({ propname: "propvalue" }); 

 $("span").plugin("update"); 

这荒谬地类似于Twitter Bootstrap的JavaScript模板 。 但是,它并没有完全从那里开始。 我有使用.data()的悠久历史。

别忘了妥善包装。

如果你想使用这样的插件:

 // Init plugin $('a').myplugin({ color: 'blue' }); // Call the changeBG method $('a').myplugin('changeBG') // chaining .each(function () { // call the get method href() console.log( $(this).myplugin('href') ); }); 

或者如果每个元素需要独立的插件实例:

 $('a').each(function () { $(this).myplugin(); }); 

你会想要像这样设置你的插件:

 /* * 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). var pluginName = "myplugin", // the name of using in .data() dataPlugin = "plugin_" + pluginName, // default options defaults = { color: "black" }; function privateMethod () { console.log("private method"); } // The actual plugin constructor function Plugin() { /* * Plugin instantiation * * You already can access element here * using this.element */ this.options = $.extend( {}, defaults ); } Plugin.prototype = { init: function ( options ) { // extend options ( http://api.jquery.com/jQuery.extend/ ) $.extend( this.options, options ); /* * Place initialization logic here */ this.element.css( 'color', 'red' ); }, destroy: function () { // unset Plugin data instance this.element.data( dataPlugin, null ); }, // public get method href: function () { return this.element.attr( 'href' ); }, // public chaining method changeBG: function ( color = null ) { color = color || this.options['color']; return this.element.each(function () { // .css() doesn't need .each(), here just for example $(this).css( 'background', color ); }); } } /* * Plugin wrapper, preventing against multiple instantiations and * allowing any public function to be called via the jQuery plugin, * eg $(element).pluginName('functionName', arg1, arg2, ...) */ $.fn[pluginName] = function ( arg ) { var args, instance; // only allow the plugin to be instantiated once if (!( this.data( dataPlugin ) instanceof Plugin )) { // if no instance, create one this.data( dataPlugin, new Plugin( this ) ); } instance = this.data( dataPlugin ); /* * because this boilerplate support multiple elements * using same Plugin instance, so element should set here */ instance.element = this; // Is the first parameter an object (arg), or was omitted, // call Plugin.init( arg ) if (typeof arg === 'undefined' || typeof arg === 'object') { if ( typeof instance['init'] === 'function' ) { instance.init( arg ); } // checks that the requested public method exists } else if ( typeof arg === 'string' && typeof instance[arg] === 'function' ) { // copy arguments & remove function name args = Array.prototype.slice.call( arguments, 1 ); // call the method return instance[arg].apply( instance, args ); } else { $.error('Method ' + arg + ' does not exist on jQuery.' + pluginName); } }; }(jQuery, window, document)); 

笔记:

  • 此样板文件不会对每个方法调用使用.each(),您应该在需要时使用.each()
  • 允许重新初始化插件,但只会创建一个实例
  • 包括destroy方法的示例

参考: https : //github.com/jquery-boilerplate/boilerplate/wiki/Another-extending-jQuery-boilerplate

你试过jQuery UI Widget Factory吗?

有一点学习曲线,但我现在喜欢它,处理选项,默认并允许方法,保持一切紧张非常花哨:)


编辑

jQuery UI Widget Factory是jQuery UI Library的一个独立组件,它提供了一种简单的,面向对象的方式来创建有状态的jQuery插件。

– 有状态插件和Widget工厂简介 。

在大多数情况下,我不认为额外的开销会让人担心。 这些天我用coffescript编写,一切都被编译,缩小和压缩,所以这里和那里的一些额外的行没有太大的区别。 我对网站速度的研究似乎表明,HTTP请求的数量是一个大问题 – 事实上,让我在这条轨道上工作的前同事适用于基于浏览器的游戏,而且速度极快。