【问题标题】:How to Extend Twitter Bootstrap Plugin如何扩展 Twitter Bootstrap 插件
【发布时间】:2012-02-26 13:58:14
【问题描述】:

我正在研究 Twitter 的 Bootstrap,现在想尝试在插件中添加一些功能,但我不知道该怎么做。以模态插件为例(http://twitter.github.com/bootstrap/javascript.html#modals),我想在插件中添加一个新函数,可以像标准插件方法一样调用它。我认为最接近的是以下代码,但是当我尝试访问时,我得到的只是该函数不是对象的一部分。

有什么建议吗?这是我尝试过的似乎最接近我需要做的事情:

 $.extend($.fn.modal, { 
    showFooterMessage: function (message) { 
        alert("Hey"); 
    } 
}); 

那我想这样称呼它:

  $(this).closest(".modal").modal("showFooterMessage"); 

编辑:好的,我想出了如何做到这一点:

(function ($) {
    var extensionMethods = {
        displayFooterMessage: function ($msg) {
            var args = arguments[0]
            var that = this;

            // do stuff here
        }
    }

    $.extend(true, $.fn.modal.Constructor.prototype, extensionMethods);
})(jQuery);

现有 Bootstrap 插件集的问题在于,如果有人想扩展它们,则没有一个新方法可以接受参数。我试图“解决”这个问题是在插件函数调用中添加参数的接受。

$.fn.modal = function (option) {
    var args = arguments[1] || {};
    return this.each(function () {
        var $this = $(this)
        , data = $this.data('modal')
        , options = typeof option == 'object' && option

        if (!data) $this.data('modal', (data = new Modal(this, options)))

        if (typeof option == 'string') data[option](args)
        else data.show()

    }) // end each
} // end $.fn.modal

【问题讨论】:

  • 如果此编辑旨在作为答案,您现在应该可以将其作为答案发布。请继续这样做:)
  • 回答我自己的问题似乎有点蹩脚;)
  • 哦,别担心。这是完全正常的 - 即使I've done it once :)

标签: jquery jquery-plugins twitter-bootstrap


【解决方案1】:

+1 表示 David 接受的上述答案。但如果我可以再简化一点,我会像这样调整DEFAULTS 扩展和$fn.modal 扩展:

!function($) {

    'use strict';

    // save the original function object
    var _super = $.fn.modal;

    // create a new constructor
    var Modal = function(element, options) {

        // do custom constructor stuff here

        // call the original constructor
        _super.Constructor.apply( this, arguments );

    }

    // add custom defaults
    Modal.DEFAULTS = $.extend( _super.defaults, {
         myCustomOption: true
    });

    // extend prototypes and add a super function
    Modal.prototype = $.extend({}, _super.Constructor.prototype, {
        constructor: Modal,
        _super: function() {
            var args = $.makeArray(arguments);
            _super.Constructor.prototype[args.shift()].apply(this, args);
        },
        show: function() {

            // do custom method stuff

            // call the original method
            this._super('show');
        },
        myCustomMethod: function() {
            alert('new feature!');
        }
    });

    // Copied exactly from Bootstrap 3 (as of Modal.VERSION  = '3.3.5')
    // Notice: You can copy & paste it exactly, no differences!
    function Plugin(option, _relatedTarget) {
        return this.each(function () {
            var $this   = $(this)
            var data    = $this.data('bs.modal')
            var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)

            if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
            if (typeof option == 'string') data[option](_relatedTarget)
            else if (options.show) data.show(_relatedTarget)
        })
    }

    // override the old initialization with the new constructor
    $.fn.modal = $.extend(Plugin, $.fn.modal);

}(jQuery);

【讨论】:

  • 正如@benembery 所建议的,默认选项附加到构造函数命名空间。对于这个解决方案,我认为自定义默认值需要是 // 添加自定义默认值 Modal.DEFAULTS = $.extend( _super.Constructor.DEFAULTS, { myCustomOption: true });
【解决方案2】:

对于希望使用 Bootstrap 3 执行此操作的任何人。插件布局已有所更改,所有 Bootstrap 3 插件的默认选项都附加到插件构造函数:

var _super = $.fn.modal;
$.extend(_super.Constructor.DEFAULTS, {
       foo: 'bar',
       john: 'doe'
});

【讨论】:

    【解决方案3】:

    为了记录,有一个简单的方法可以覆盖或扩展现有功能:

    var _show = $.fn.modal.Constructor.prototype.show;
    
    $.fn.modal.Constructor.prototype.show = function() {
        _show.apply(this, arguments);
        //Do custom stuff here
    };
    

    不包括自定义参数,但使用上面的方法也很容易;而不是使用applyarguments,在函数定义中指定原始参数和自定义参数,然后使用原始参数调用原始_show(或任何一个),最后用新参数做其他事情论据。

    【讨论】:

    • 不知何故,其他方法每次都会陷入无限循环......这个完美! +1 为简单起见:)
    • 这很好,但如果你想扩展构造函数(在构造上做一些事情,例如添加绑定/等),那就不好了。
    • @DavidGraham 你也可以重写构造函数,它就在原型中。在上面的示例中,您希望覆盖 $.fn.modal.Constructor.prototype.constructor 方法。
    【解决方案4】:

    这是一个旧线程,但我只是使用以下模式对模态进行了一些自定义扩展:

    // save the original function object
    var _super = $.fn.modal;
    
    // add custom defaults
    $.extend( _super.defaults, {
        foo: 'bar',
        john: 'doe'
    });
    
    // create a new constructor
    var Modal = function(element, options) {
    
        // do custom constructor stuff here
    
         // call the original constructor
        _super.Constructor.apply( this, arguments );
    
    }
    
    // extend prototypes and add a super function
    Modal.prototype = $.extend({}, _super.Constructor.prototype, {
        constructor: Modal,
        _super: function() {
            var args = $.makeArray(arguments);
            _super.Constructor.prototype[args.shift()].apply(this, args);
        },
        show: function() {
    
            // do custom method stuff
    
            // call the original method
            this._super('show');
        }
    });
    
    // override the old initialization with the new constructor
    $.fn.modal = $.extend(function(option) {
    
        var args = $.makeArray(arguments),
            option = args.shift();
    
        return this.each(function() {
    
            var $this = $(this);
            var data = $this.data('modal'),
                options = $.extend({}, _super.defaults, $this.data(), typeof option == 'object' && option);
    
            if ( !data ) {
                $this.data('modal', (data = new Modal(this, options)));
            }
            if (typeof option == 'string') {
                data[option].apply( data, args );
            }
            else if ( options.show ) {
                data.show.apply( data, args );
            }
        });
    
    }, $.fn.modal);
    

    这样就可以了

    1) 添加您自己的默认选项

    2) 使用自定义参数创建新方法并访问原始(超级)函数

    3) 在调用原始构造函数之前和/或之后在构造函数中做一些事情

    【讨论】:

    • David - 如果您能看看我关于您使用的覆盖初始化语法的问题,我将不胜感激:stackoverflow.com/q/39751235
    • 你有与 Bootstrap 4 类似的解决方案吗?
    【解决方案5】:

    作为参考,我遇到了类似的问题,所以我 "extended" the Typeahead plugin 通过分叉并在插件脚本本身中添加我需要的功能。

    如果您必须更改源代码,那么它并不是真正的扩展,所以我认为将所有修改放在一个地方会更容易。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-06-10
      • 1970-01-01
      • 1970-01-01
      • 2013-07-14
      • 1970-01-01
      • 2012-12-26
      • 2011-11-18
      相关资源
      最近更新 更多