Bootstrap源码解析(一):JavaScript部分

本文共4块
Bootstrap是基于jQuery实现的UI库,没有jQuery就无法运行。

结构图

如图共4个部分,着重看看第四部分(结构体都类似),以Alert为例。


结构图
Bootstrap源码1.png

Bootstrap源码2.png
  • $.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);

你可能感兴趣的:(Bootstrap源码解析(一):JavaScript部分)