在自定义jQuery插件中放置jQuery插件

时间:2018-03-23 08:48:45

标签: javascript jquery jquery-plugins

我有一个基于this boilerplate的小插件。

一切正常,但是想要专注于插件中的一个小型“帮助器”功能的放置。这是片段。

(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()几乎相同的方式设置表单元素值时,我可以轻松使用它。

我的问题如下:

  • 是否有某种方法可以将其设置为私有?
  • 如果没有,将它放在函数内部,就像它在 摆弄一个好的方法去添加像小帮手这样的小函数 此?
  • 或者是否会推荐其他方法?
  • 或许像这样的帮手应该只是他们自己的独立 插件吗? (可能只是一个偏好的东西)

1 个答案:

答案 0 :(得分:0)

问题是,执行$.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(…)