使用类和原型编写jQuery插件

13

使用类和原型这种方式编写插件好还是不好,这段代码有什么缺点?

function PluginName(jqueryObject, options) {

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

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

1
这两种方法都是公共的,或者说可以通过这段代码访问。 - Joe
缺点:无法使用jQuery的流畅接口。 - Felix Kling
谢谢,那么在这里声明私有方法的最佳方式是什么? - Marvin3
3个回答

29

请参考jQuery插件开发最佳实践:

  • 始终使用(function( $ ){ // 插件代码在此处 })( 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'
});

如何在方法之间共享数据? - kolobok

8
首先,正如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 在插件编写指南中建议的模式。

(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文档以了解其含义。通过这种方式,您可以实际控制哪些方法是公共的,哪些是私有的。
编辑提示:如果您想完全保持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,以获取最终可用的示例。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接