如何扩展Twitter Bootstrap插件

时间:2012-02-04 00:28:02

标签: jquery jquery-plugins twitter-bootstrap

我正在挖掘Twitter的Bootstrap,现在想尝试为插件添加一些功能,但我无法弄清楚如何这样做。使用modal插件作为示例(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

5 个答案:

答案 0 :(得分:35)

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

// 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)在调用原始构造函数之前和/或之后在构造函数中执行操作

答案 1 :(得分:28)

对于记录,有一种简单的方法来覆盖或扩展现有函数:

var _show = $.fn.modal.Constructor.prototype.show;

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

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

答案 2 :(得分:4)

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

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

答案 3 :(得分:2)

对于任何想要使用Bootstrap 3执行此操作的人。插件布局已经改变了一点,所有Bootstrap 3插件的默认选项都附加到插件构造函数:

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

答案 4 :(得分:2)

+1以上大卫接受的答案。但如果我可以将其简化一点,我会调整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);