Как расширить модуль загрузки Bootstrap Twitter
Я копаю в Twitter Bootstrap и теперь хочу попробовать добавить некоторые функции в плагины, но я не могу понять, как это сделать. Используя modal plugin в качестве примера (http://twitter.github.com/bootstrap/javascript.html#modals), я хотел бы добавить новую функцию в плагин, который можно вызвать, как и стандартные методы плагина, Ближайший я думаю, что я пришел со следующим кодом, но все, что я получаю, когда пытаюсь получить доступ, состоит в том, что функция не является частью объекта.
Любые предложения? Это то, что я пробовал, который, кажется, ближе всего к тому, что мне нужно сделать:
$.extend($.fn.modal, {
showFooterMessage: function (message) {
alert("Hey");
}
});
Тогда я хотел бы назвать это следующим образом:
$(this).closest(".modal").modal("showFooterMessage");
EDIT: Хорошо, я понял, как это сделать:
(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
Ответы
Ответ 1
Это старый поток, но я просто сделал некоторые пользовательские расширения для модальных, используя следующий шаблон:
// 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) делать вещи в конструкторе до и/или после того, как исходный конструктор называется
Ответ 2
Для записи есть простой способ переопределить или расширить существующие функции:
var _show = $.fn.modal.Constructor.prototype.show;
$.fn.modal.Constructor.prototype.show = function() {
_show.apply(this, arguments);
//Do custom stuff here
};
Не распространяется на пользовательские аргументы, но это также легко, как описано выше; вместо использования apply
и arguments
укажите исходные аргументы плюс пользовательские в определении функции, затем вызовите исходный _show
(или в зависимости от того, что это) с исходными аргументами и, наконец, выполните другие действия с новым аргументы.
Ответ 3
Для справки у меня была аналогичная проблема, поэтому я "расширил" плагин Typeahead путем разметки и добавления функциональности, необходимой мне в плагине script сам.
Если вам нужно изменить источник, это не действительно расширение, так что я решил, что было проще просто внести все мои изменения в одном месте.
Ответ 4
Для тех, кто хочет сделать это с помощью Bootstrap 3. Плагин плагина немного изменил параметры по умолчанию для всех плагинов Bootstrap 3, подключенных к конструктору плагинов:
var _super = $.fn.modal;
$.extend(_super.Constructor.DEFAULTS, {
foo: 'bar',
john: 'doe'
});
Ответ 5
+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);