2012-02-04 107 views
44

我正在挖掘Twitter的Bootstrap,现在想尝试向插件添加一些功能,但我无法弄清楚如何实现。以模态插件为例(http://twitter.github.com/bootstrap/javascript.html#modals),我想添加一个新的函数到插件,可以调用标准插件方法。我认为我最接近的是以下代码,但是当我尝试访问时所获得的所有内容都是该函数不是对象的一部分。如何扩展Twitter引导程序插件

有什么建议吗?这是我曾尝试这似乎是最接近于什么,我需要做的:

$.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); 

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

$.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

如果此编辑本来是一个答案,你现在应该可以将它张贴作为一个答案。请继续努力:) – BoltClock 2012-03-16 19:05:55

+0

看起来有点跛脚回答我自己的问题;) – AlexGad 2012-04-04 18:59:21

+1

哦,别担心。这是完全正常的 - 即使[我做过一次](http://stackoverflow.com/questions/5493149/how-do-i-make-a-wpf-window-movable-by-dragging-the-extended-玻璃框架):) – BoltClock 2012-04-04 19:04:06

回答

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)在原始const()函数之前和/或之后在构造函数中做东西ructor被称为

+0

大卫 - 我会很感激,如果你可以看看我的问题关于你使用的重写初始化语法:http://stackoverflow.com/q/39751235 – 2016-09-29 11:22:17

4

仅供参考,我让我"extended" the Typeahead plugin通过派生并添加我需要的插件脚本本身的功能也有类似的问题。

如果你不得不改变源代码,反正它不是一个扩展,所以我觉得只是把我所有的修改放在一个地方更容易。

26

为了记录有覆盖或扩展现有功能的简单方法:

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

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

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

+0

不知何故其他方法会碰到每次都有一个无限循环......这个作品完美无缺! +1为简单:) – 2013-06-18 11:17:03

+0

这是伟大的,但不是很好,如果你想扩展构造函数(做建设,如添加绑定/等)。 – prograhammer 2015-07-06 15:45:59

+1

@DavidGraham你也可以重载构造函数,它就在原型中。在上面的例子中,你想重写'$ .fn.modal.Constructor.prototype.constructor'方法。 – Mahn 2015-07-06 17:06:28

2

对于任何寻求与引导3.插件布局要做到这一点已经改变了一下所有的引导3插件默认选项连接到插件的构造函数:

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

+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); 
+0

正如@benembery所建议的,默认选项被附加到构造函数名称空间。对于这个解决方案,我认为自定义默认值需要为 // add custom defaults Modal.DEFAULTS = $.extend(_super.Constructor.DEFAULTS, { myCustomOption: true }); jakxnz 2016-07-25 05:05:59