jQuery 插件在自定义 jQuery 插件中的位置

Placement for jQuery plugin within a custom jQuery plugin

我有一个基于 this boilerplate.

的小插件

一切正常,但我想专注于插件中一个小的 "helper" 函数的放置。这是片段。

(function ($, window, document, undefined) {
 
    var pluginName = 'test',
  defaults = {};
 
    function Plugin(element, options) {
        this.element = element;
        this.options = $.extend({}, defaults, options);
        this.init();
    }

    Plugin.prototype = {
        init: function() {
            $(this.element).find(':input').each(function() {
    $(this).setValue('value');
   });
        }
    };
 
 $.fn.setValue = function(value) {
  var $el = $(this);
  if ($el.prop('type') == 'checkbox') {
   $el.prop('checked', true);
  } else {
   $el.val(value);
  }
 };
 
    $.fn[pluginName] = function ( options ) {
        return this.each(function () {
            if (!$.data(this, "plugin_" + pluginName)) {
                $.data(this, "plugin_" + pluginName,
                new Plugin( this, options ));
            }
        });
    };

})(jQuery, window, document);

$('#apply-test').click(function(e) {
 e.preventDefault();
 $('#test').test();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container mt-5">
    <form id="test">
        <div class="form-group">
            <label for="name">Name</label>
            <input type="text" name="name" id="name" class="form-control">
        </div>
        <div class="form-group">
            <label for="email">Email</label>
            <input type="text" name="email" id="email" class="form-control">
        </div>
        <div class="form-group">
            <div class="form-check">
                <input type="checkbox" name="notifications" id="notifications" class="form-check-input">
                <label for="notifications" class="form-check-label">
                    Receive Notifications
                </label>
            </div>
        </div>
        <div class="form-group">
            <button type="submit" id="apply-test" class="btn btn-primary">Apply Test</button>
        </div>
    </form>
</div>

在插件中,您会注意到另一个类似这样的功能:

$.fn.setValue = function(value) {
    var $el = $(this);
    if ($el.prop('type') == 'checkbox') {
        $el.prop('checked', true);
    } else {
        $el.val(value);
    }
};

现在我可以将该代码放在该插件内部或外部我喜欢的任何位置,并且它工作得很好。此外,我使用这样的函数的原因是,在以与使用标准 $(el).val().[=17= 几乎相同的方式设置表单元素值时,我可以轻松使用它]

我的问题如下:

问题是,一旦 $.fn.setValue = function … 被执行,setValue 函数就可以在你的应用程序中的任何地方被调用(比如 $('randomSelector').setValue()),那就是可能不是你的本意。

要使 setValue 函数只能从您的插件中访问,您可以使其行为依赖于提供的参数:

(function ($, window, document) {
    // …
// Make setValue only accessible through the plugin
    function setValue = function(value) {
      if (this.prop('type') == 'checkbox') {
        this.prop('checked', true);
      } else {
        this.val(value);
      }
    };

    $.fn[pluginName] = function(options, more) {
// Test arguments and call setValue when appropriate
      if (options === 'set') {
        // Apply setValue on the current jquery Collection
        setValue.apply(this, more);
        // Make your plugin "chainable"
        return this;

      // Eventually handle other scenarios
      } else /* if (…) */ { ; }

      // Your default plugin behavior
      return this.each(function() {
        if (!$.data(this, "plugin_" + pluginName)) {
          $.data(this, "plugin_" + pluginName,
            new Plugin(this, options));
        }
      });
    };

})(jQuery, window, document);

然后你这样调用你的插件:

$('#apply-test').click(function(e) {
  e.preventDefault();
  // Call setValue
  $('#test').test('set', 1);
  // Standard call
  $('#test').test();
});

旁注:在插件函数 $.fn.xxx = function() {/*here*/} 中,this 指向触发插件函数调用的 jquery 集合。因此 var $el = $(this); 在这种情况下是无用的(它只会增加开销),只需使用 this 或最终使用 this.eq(0)this.each(…).