使用类和原型编写jQuery插件

时间:2011-08-22 14:46:53

标签: javascript jquery plugins

以这种方式编写插件是好事还是坏事(使用类和原型),这些代码有什么不妥之处?

function PluginName(jqueryObject, options) {

}
PluginName.prototype = {
    publicMethod:function() {
    },
    _privateMethod:function() {
    }
}

// Initializing 
var myPluginInstance = new PluginName($(".mySelector"), {myOption:1});
myPluginInstance.publicMethod();

3 个答案:

答案 0 :(得分:27)

有关最佳做法,请参阅jQuery docs on plugin authoring

  • 始终将您的插件包装在(function( $ ){ // plugin goes here })( jQuery );
  • 不要在插件函数的直接范围内冗余地包装this关键字
  • 除非您从插件中返回内在值,否则请始终让插件的函数返回this关键字以保持可链接性。
  • 不需要大量的参数,而是将插件设置传递给可以通过插件默认值扩展的对象文字。
  • 不要在每个插件中使用多个命名空间来混淆jQuery.fn对象。
  • 始终命名方法,事件和数据。

实施例

(function( $ ){

  var methods = {
    init : function( options ) { // THIS },
    show : function( ) { // IS   },
    hide : function( ) { // GOOD },
    update : function( content ) { // !!! }
  };

  $.fn.tooltip = function( method ) {

    // Method calling logic
    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.tooltip' );
    }    

  };

})( jQuery );

用法:

$('div').tooltip(); // calls the init method
$('div').tooltip({  // calls the init method
  foo : 'bar'
});
$('div').tooltip('hide'); // calls the hide method
$('div').tooltip('update', 'This is the new tooltip content!'); // calls the update method

默认值和选项示例

(function( $ ){

  $.fn.tooltip = function( options ) {  

    var settings = {
      'location'         : 'top',
      'background-color' : 'blue'
    };

    return this.each(function() {        
      // If options exist, lets merge them
      // with our default settings
      if ( options ) { 
        $.extend( settings, options );
      }

      // Tooltip plugin code here

    });

  };
})( jQuery );

用法:

$('div').tooltip({
  'location' : 'left'
});

答案 1 :(得分:6)

首先,正如Spycho所说,总是将你的插件包装在

(function( $ ){
    $.fn.PluginName = function() {
        // plugin goes here
    };
})( jQuery );

避免与使用美元符号的其他图书馆发生冲突。

其次,如果扩展jQuery.fn对象,则使用类似$("#myDiv")的调用选择作为this传递给插件。这样,您就不必像以前那样将选择作为参数传递给插件。

第三,你做得正确,他们建议你把选项作为一个对象而不是单个参数传递给插件,这样你就可以轻松拥有并覆盖默认值:

(function( $ ){
    $.fn.PluginName = function(options) {
        var settings = { myOption: 1 };
        if (options) {
            $.extend( settings, options );
        }
        // plugin goes here
    };
})( jQuery );

第四,你创建_privateMethod的方式实际上并不是私有的,为此你可以按照jQuery在plugin authoring guidelines中建议的模式

(function( $ ){
    var methods = {
        publicMethod: function(options) {
           var settings = { myOption: 1 };
            if (options) {
                $.extend( settings, options );
            }
        },
        _privateMethod: function() {}            
    }
    $.fn.PluginName = function(methodName, options) {
        // use some logic to control what methods are public
        if (methodName == "publicMethod") {
            return publicMethod.apply(this, Array.prototype.slice.call( arguments, 1 ));
        }
    };
})( jQuery );

这使用applycall这些功能强大的内置函数方法来设置函数调用的范围,请参阅MDN reference以了解其中的内容。这样,您实际上可以控制哪些方法是公共方法与私有方法。

编辑:最后,如果你想完全维护jQuery的流畅界面并让你的插件接受$()传递的选择并传递它,换句话说,是可链接的,你的方法需要返回给定的对象集合:

(function( $ ){
    var methods = {
        publicMethod: function(options) {
           var settings = { myOption: 1 };
            if (options) {
                $.extend( settings, options );
            }
            return this.each(function() {
                this.value = (this.value * 1) + settings.myOption;
            });
        },
        _privateMethod: function() {}            
    }
    $.fn.PluginName = function(methodName, options) {
        // use some logic to control what methods are public
        if (methodName == "publicMethod") {
            return methods.publicMethod.apply(this, Array.prototype.slice.call( arguments, 1 ));
        }
    };
})( jQuery );

有关最终的工作示例,请参阅此jsFiddle

答案 2 :(得分:0)

编写jQuery插件的最简单方法(特别是如果它们有一些内部状态)是使用jQuery UI Widget Factory。

我不建议您重新发明轮子并自己编写大量的样板代码。

https://learn.jquery.com/jquery-ui/widget-factory/why-use-the-widget-factory/ https://learn.jquery.com/plugins/stateful-plugins-with-widget-factory/