我正在挖掘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
答案 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
};
不包括自定义参数,但使用上述方法也很容易;而不是使用apply
和arguments
,在函数定义中指定原始参数加上自定义参数,然后使用原始参数调用原始_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);