6

我不确定这是否是一个stackoverflow问题,因为它有点笼统,如果是,请原谅我。

假设我有以下标记:

<div class="plugin"> ... </div>
<div class="plugin"> ... </div>
<div class="plugin"> ... </div>

而且我不想运行一个 jquery 插件并将每个具有plugin该类的元素传递给它:

$(".plugin").myPlugin();

插件代码如下所示:

;(function ( $, window, undefined ) {

  var myPlugin = 'myPlugin',
      document = window.document,
      defaults = {
        propertyName: "value"
      };

  // The actual plugin constructor
  function Plugin( element, options ) {
    this.element = element;

    this.options = $.extend( {}, defaults, options) ;

    this._defaults = defaults;
    this._name = myPlugin;

    this.init();
  }

  Plugin.prototype.init = function () {

  };

  // A really lightweight plugin wrapper around the constructor, 
  // preventing against multiple instantiations
  $.fn[myPlugin] = function ( options ) {
    return this.each(function () {
      if (!$.data(this, 'plugin_' + myPlugin)) {
        $.data(this, 'plugin_' + myPlugin, new Plugin( this, options ));
      }
    });
  }
}(jQuery, window));

当我运行这段代码时,看起来插件构造函数正在为每个类名为myPlugin. 我认为它会在整个 div 集合上运行插件,并且只调用一次构造函数。

那么它是怎样工作的?是否为类选择器返回的每个元素创建了插件实例?

4

3 回答 3

2

也许以下评论会有所帮助:

$.fn[myPlugin] = function ( options ) {
    /* "this" is collection of elements from selector*/
    return this.each(function () {
        /* "this" is individual element due to being inside "each" loop*/
      if (!$.data(this, 'plugin_' + myPlugin)) {
        $.data(this, 'plugin_' + myPlugin, new Plugin( this, options ));
      }
    });
  }
于 2013-01-07T00:37:44.107 回答
2

从顶部

$(".plugin").myPlugin();

jQuery 选择器

jQuery 将采用选择器.plugin,然后运行其通常的选择过程,生成一个 jQuery 对象(带有可用于链接的 jQuery 原型),该对象还包含结果的长度、结果数组和使用的选择器。

因此,$(".plugin")使用上述内容返回此对象。

我的插件()

myPlugin()是一个函数调用。它是针对从$(".plugin"). 此函数位于定义它的位置:$.fn[myPlugin]. fn是 jQuery 向其基本原型添加功能的方式。请注意,这只调用一次

$.fn[myPlugin] = 函数

此处调用的函数现在运行。它运行在this,这是上面提到的原始 jQuery 对象(包括来自选择器的结果数组)。this.each(function () {...},其中 jQuery 的each函数将遍历 jQuery 对象的结果。在您的示例中,有 3 个 div。

每次迭代运行

if (!$.data(this, 'plugin_' + myPlugin)) {
 $.data(this, 'plugin_' + myPlugin, new Plugin( this, options ));
}

第一行是一个条件语句,它查看名为“plugin_myPlugin”的数据对象(myPlugin 是一个常量字符串值)是否存在于当前元素(这是这 3 个 div 之一)上。首先运行此代码时,他们都没有这个。

$.data(this, 'plugin_' + myPlugin, new Plugin(this, options));

这行代码将this对象(即当前的 html 元素)传递给 jQuery 的data方法,该方法将对象添加到由名称索引的元素中。本例中的名称是“plugin_myPlugin”,对象是...

新插件(这个,选项)

$.fn[myPlugin]插件是在您的示例范围内本地定义的函数。它被定义为function Plugin( element, options ) {...}

功能插件(元素,选项){...}

这个函数将接受一个元素,它是从迭代中传递的each——在这个例子中是 3 个 div 之一——以及最初作为参数发送的选项$.fn[myPlugin](在这种情况下,没有传入,可以看出与myPlugin().

this.element该函数接受这些参数,并使用、this.optionsthis._defaults和将它们构建到当前 Function 对象上this._name,然后调用 init 函数(此处为空)。

毕竟构造了一个 Function 对象,然后使用 jQuery 的data方法将其附加到当前元素。

执行摘要

扩展函数myPlugin将为从使用的选择器生成的 jQuery 对象中的每个元素运行一次。扩展函数从定义的函数Plugin为每个符合条件的元素创建一个新的 Function 对象(因此在每个元素上运行构造函数,在这个确切的示例中运行 3 次)。

于 2013-01-07T01:14:54.713 回答
1

是否为类选择器返回的每个元素创建了插件实例?

的。this.each因为当您在插件构造函数中调用并Plugin为每个元素初始化一个新的构造函数时,您正在循环遍历元素。

如果您想为集合运行单个自定义构造函数,请不要这样做this.each,只需传递thisPlugin构造函数(尽管您可能需要重新考虑使用插件的“缓存” jQuery.data

于 2013-01-07T00:33:06.890 回答