本文共4块
Bootstrap是基于jQuery实现的UI库,没有jQuery就无法运行。
结构图
如图共4个部分,着重看看第四部分(结构体都类似),以Alert为例。
$.fn[NAME] = Alert._jQueryInterface;
定义了jQuery的扩展,$.fn是指jquery的命名空间,加上fn上的方法及属性,会对jquery实例每一个有效:$.fn[NAME] === jQuery.prototype[NAME]
,它对每个$实例生效,这样就可以调用了 :
$("#alert1"). alert();
我们再来看看另外一个api:
$('#identifier').alert('close');
会调用Alert定义中的Alert.prototype.close
,并将$('#identifier')
作为参数传入;Alert.prototype.close
方法中会查找到class="alert"
的父元素, 再调用_triggerCloseEvent
将父元素直接关闭掉,其实低层会调用jQuery中的$(element).trigger($.Event(Event.CLOSE));
,
最后,如果没有阻止事情,会_removeElement
,其实就是将alert隐藏起来,并不是删除dom。-
2个钩子方法,会在相应事件调用时被钩子住:
$('#myalert').bind('close.bs.alert', function () { // 当调用 close 实例方法时立即触发该事件。 })
$('#myalert').bind('closed.bs.alert', function () { // 当警告框被关闭时触发该事件(将等待 CSS 过渡效果完成)... })
/** * -------------------------------------------------------------------------- * Bootstrap (v4.0.0-alpha.6): alert.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * -------------------------------------------------------------------------- */ var Alert = function ($) { /** * ------------------------------------------------------------------------ * Constants * ------------------------------------------------------------------------ */ var NAME = 'alert'; var VERSION = '4.0.0-alpha.6'; var DATA_KEY = 'bs.alert'; var EVENT_KEY = '.' + DATA_KEY; var DATA_API_KEY = '.data-api'; var JQUERY_NO_CONFLICT = $.fn[NAME]; var TRANSITION_DURATION = 150; var Selector = { DISMISS: '[data-dismiss="alert"]' }; var Event = { CLOSE: 'close' + EVENT_KEY, CLOSED: 'closed' + EVENT_KEY, CLICK_DATA_API: 'click' + EVENT_KEY + DATA_API_KEY }; var ClassName = { ALERT: 'alert', FADE: 'fade', SHOW: 'show' }; /** * ------------------------------------------------------------------------ * Class Definition * ------------------------------------------------------------------------ */ var Alert = function () { function Alert(element) { _classCallCheck(this, Alert); // 第27行定义的:function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } this._element = element; } // getters // public Alert.prototype.close = function close(element) { element = element || this._element; var rootElement = this._getRootElement(element); var customEvent = this._triggerCloseEvent(rootElement); if (customEvent.isDefaultPrevented()) { return; } this._removeElement(rootElement); }; Alert.prototype.dispose = function dispose() { $.removeData(this._element, DATA_KEY); this._element = null; }; // private Alert.prototype._getRootElement = function _getRootElement(element) { var selector = Util.getSelectorFromElement(element); var parent = false; if (selector) { parent = $(selector)[0]; } if (!parent) { parent = $(element).closest('.' + ClassName.ALERT)[0]; } return parent; }; Alert.prototype._triggerCloseEvent = function _triggerCloseEvent(element) { var closeEvent = $.Event(Event.CLOSE); $(element).trigger(closeEvent); return closeEvent; }; Alert.prototype._removeElement = function _removeElement(element) { var _this2 = this; $(element).removeClass(ClassName.SHOW); if (!Util.supportsTransitionEnd() || !$(element).hasClass(ClassName.FADE)) { this._destroyElement(element); return; } $(element).one(Util.TRANSITION_END, function (event) { return _this2._destroyElement(element, event); }).emulateTransitionEnd(TRANSITION_DURATION); }; Alert.prototype._destroyElement = function _destroyElement(element) { $(element).detach().trigger(Event.CLOSED).remove(); }; // static Alert._jQueryInterface = function _jQueryInterface(config) { return this.each(function () { var $element = $(this); var data = $element.data(DATA_KEY); if (!data) { data = new Alert(this); $element.data(DATA_KEY, data); } if (config === 'close') { data[config](this); } }); }; Alert._handleDismiss = function _handleDismiss(alertInstance) { return function (event) { if (event) { event.preventDefault(); } alertInstance.close(this); }; }; _createClass(Alert, null, [{ key: 'VERSION', get: function get() { return VERSION; } }]); return Alert; }(); /** * ------------------------------------------------------------------------ * Data Api implementation * ------------------------------------------------------------------------ */ $(document).on(Event.CLICK_DATA_API, Selector.DISMISS, Alert._handleDismiss(new Alert())); /** * ------------------------------------------------------------------------ * jQuery * ------------------------------------------------------------------------ */ $.fn[NAME] = Alert._jQueryInterface; $.fn[NAME].Constructor = Alert; $.fn[NAME].noConflict = function () { $.fn[NAME] = JQUERY_NO_CONFLICT; return Alert._jQueryInterface; }; return Alert; }(jQuery);