1

jQuery 样板站点,我想出了一个如下所示的插件:

;(function($, window, document, undefined){
  "use strict"; 

  var defaults = {
        abc: 1,
        def: 'xyz'        
      };

  function Plugin(element, options){
    this.options = $.extend({}, defaults, options, element.dataset);
    this.element = element;
  }

  plugin.prototype = {
     goTo: function(where){
       // ...
     },

     close: function(){
       $(this.element).removeData('_myplug');   
     }
  };

  $.fn.myPlugin = function(options){
    return this.each(function(){
      if(!$.data(this, '_myplug'))
        $.data(this, '_myplug', new Plugin(this, options));

      if($.isPlainObject(options))
        return;

      // here how to check if 'options' matches one of the
      // functions, then call it with the rest of the variables
    });
  };

})(jQuery, window, document);

所以它可以像这样使用

$('.stuff').myPlugin({abc: 5});

我如何还允许调用公共方法,如下所示:

$('.stuff').myPlugin('goTo', 'top');
// should call instance.goTo('top');

或者:

$('.stuff').myPlugin('close');
// should call instance.close();

?

我知道可以通过在 $.fn.myPlugin 函数声明中添加更多变量,然后使用 if 语句检查 options 是否为字符串,但我想知道是否有更好的方法来做到这一点


例如,在 PHP 中,它看起来像这样:

$args = func_get_args();
$arg1 = array_shift($args);
return call_user_func_array(array($this, $arg1), $args);

我怎样才能在javascript中做到这一点?

4

1 回答 1

1

简而言之,您可以这样做:

var instance = $.data(this, '_myplug');
if (typeof options === "string" && typeof instance[options] === "function") {
    instance[options].apply(instance, arguments.slice(1));
}

解释

首先,您检查是否options是一个字符串,以及您的实例是否包含名称为options.

然后你使用arguments数组。您可以从任何函数内部访问此数组,它包含调用函数时传递的所有参数(无论这些参数是否是函数定义的一部分)。

最后,您可以使用该function.apply()方法将参数数组的修改版本(除第一个参数外的所有参数)传递给实例的方法。

于 2013-06-10T20:39:53.417 回答