【问题标题】:jQuery plugin creation and public facing methodsjQuery 插件创建和面向公众的方法
【发布时间】:2012-10-04 12:28:33
【问题描述】:

我创建了一个插件,可以使用 DIV 将 HTML 选择框转换为自定义下拉菜单。

一切正常,但我想让它变得更好一点。 see my jsFiddle

在插件的最后,我有 2 个方法,slideDownOptions 和 slideUpOptions,我想让这些方法在插件之外可用,以便其他事件可以触发操作。

我有点困惑如何做到这一点,更具体地说,如何从插件内部和插件外部调用方法。

任何帮助总是很感激

【问题讨论】:

    标签: jquery plugins methods public creation


    【解决方案1】:

    考虑使用面向对象的代码重构您的插件。有了这个,你可以为你的插件制作 API,比如 jQuery UI API。所以你可以访问插件方法,如:

    $('select').customSelect(); // apply plugin to elements
    $('select').customSelect('resetOpacity'); // call method resetOpacity();
    $('select').customSelect('setOpacity', 0.5); // call method with arguments
    

    创建此类插件的基本模板如下所示:

    // plugin example
    (function($){
        // custom select class
        function CustomSelect(item, options) {
            this.options = $.extend({
                foo: 'bar'
            }, options);
            this.item = $(item);
            this.init();
        }
        CustomSelect.prototype = {
            init: function() {
                this.item.css({opacity:0.5});
            },
            resetOpacity: function() {
                this.setOpacity('');
            },
            setOpacity: function(opacity) {
                this.item.css({opacity:opacity});
            }
        }
    
        // jQuery plugin interface
        $.fn.customSelect = function(opt) {
            // slice arguments to leave only arguments after function name
            var args = Array.prototype.slice.call(arguments, 1);
            return this.each(function() {
                var item = $(this), instance = item.data('CustomSelect');
                if(!instance) {
                    // create plugin instance and save it in data
                    item.data('CustomSelect', new CustomSelect(this, opt));
                } else {
                    // if instance already created call method
                    if(typeof opt === 'string') {
                        instance[opt].apply(instance, args);
                    }
                }
            });
        }
    
    }(jQuery));
    
    // plugin testing
    $('select').customSelect();
    

    在这里工作的 JS 小提琴:http://jsfiddle.net/XsZ3Z/

    【讨论】:

    • 喜欢这个模板。做得好!虽然 Javascript 本身不提供受保护的方法和属性,但使用您的模板很容易实现。一个普遍的约定是用下划线'_'开始受保护的方法 - 它很容易实现以防止从插件外部调用这些方法:// if instance already created call method if(typeof opt === 'string' && opt.charAt(0) !== '_') { instance[opt].apply(instance, args); }
    • 这很棒。喜欢这种方法!
    【解决方案2】:

    您必须重构代码才能使其正常工作。考虑使用jQuery Boilerplate

    ;(function ( $, window, undefined ) {
    
      var pluginName = 'convertSelect',
      document = window.document,
      defaults = {
        propertyName: "value"
      };
    
      function Plugin( element, options ) {
        this.element = element;
        this.options = $.extend( {}, defaults, options) ;
    
        this._defaults = defaults;
        this._name = pluginName;
    
        this.init();
      }
    
      Plugin.prototype = {
    
        // Private methods start with underscore
        _generateMarkup: function() {
    
          // you can access 'this' which refers to the constructor
          // so you have access the all the properties an methods
          // of the prototype, for example:
          var o = this.options
    
        },
    
        // Public methods
        slideDownOptions: function() { ... }
    
      }
    
      $.fn[ pluginName ] = function ( options ) {
        return this.each(function () {
          if (!$.data( this, 'plugin_' + pluginName ) ) {
            $.data( this, 'plugin_' + pluginName, new Plugin( this, options ) );
          }
        });
      };
    
    }(jQuery, window));
    

    然后你可以像这样调用公共方法:

    var $select = $('select').convertSelect().data('plugin_convertSelect');
    $select.slideDownOptions();
    

    我的一个项目也有类似的问题,我最近不得不重构整个事情,因为我用太多的方法污染了 jQuery 命名空间。 jQuery Boilerplate 工作得非常好,它基于官方的 jQuery 指南,但有一些曲折。如果您想查看此插件模式的实际效果,请查看https://github.com/elclanrs/jq-idealforms/tree/master/js/src

    【讨论】:

    • 同意使用 jQuery Boilerplate 开始,但后来我调整了我的允许公共函数使用它(v 在样板代码末尾进行简单更改):github.com/jquery-boilerplate/jquery-boilerplate/wiki/…
    • 再给你一个。这是恕我直言的最好方法。
    • 这种方法完全破坏了 jQuery 链接。
    猜你喜欢
    • 2012-08-17
    • 2022-01-23
    • 2018-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-23
    • 1970-01-01
    相关资源
    最近更新 更多