SOURCE

console 命令行工具 X clear

                    
>
console
var TRANSITION_END = 'bsTransitionend';
var PRIVATE_TRANSITION_END = 'transitionend';
var DURATION = 400;
var Event = {
    CLOSE: 'close',
    CLOSED: 'closed',
    CLICK_DATA_API: 'click.bs.alert.data-api',
};
var ClassName = {
    ALERT: 'alert',
    FADE: 'fade',
    SHOW: 'show'
}
var Selector = '[data-dismiss="alert"]'
$.event.special[TRANSITION_END] = {
    bindType: PRIVATE_TRANSITION_END,
    delegateType: PRIVATE_TRANSITION_END,
    // 过滤掉冒泡
    handle(event) {
        if ($(event.target).is(this)) {
            return event.handleObj.handler.apply(this, arguments);
        }
        return undefined;
    }
};

$.fn.emulateTransitionEnd = function (duration) {
    let called = false;
    $(this).one(TRANSITION_END, function () {
        called = true;
    });
    setTimeout(function () {
        if (!called) {
            $(this).trigger(PRIVATE_TRANSITION_END);
        }
    }, duration);
}

function Alert(element) {
    this._element = element;
}

Alert.prototype._getSelectorFromElement = function (element) {
    let selector = element.getAttribute('data-target') || element.getAttribute('href') || '';
    try {
        let target = $(document).find(targetSelector);
        return target.length > 0 ? selector : null;
    } catch (e) {
        return null;
    }
};

Alert.prototype._getRootElement = function (element) {
    let rootElement = Alert.prototype._getSelectorFromElement(element);
    let parent = false;
    if (rootElement) {
        return $(rootElement)[0];
    }
    return $(element).closest('.alert')[0];
};

Alert.prototype._destroyElement = function (element) {
    $(element).detach().trigger(Event.CLOSED).remove();
}

Alert.prototype._removeElement = function (element) {
    element.classList.remove(ClassName.SHOW);
    if (!element.classList.contains(ClassName.FADE)) {
        Alert.prototype._destroyElement(element);
        return;
    }
    $(element).one(TRANSITION_END, function () {
        Alert.prototype._destroyElement(element);
    }).emulateTransitionEnd(DURATION);
}

Alert.prototype.close = function (element) {
    element = element || this._element;
    var rootElement = Alert.prototype._getRootElement(element);
    var customEvent = $.Event(Event.CLOSE);
    $(rootElement).trigger(customEvent);
    Alert.prototype._removeElement(rootElement);    
}

// 绑事件
$(document).on(Event.CLICK_DATA_API, Selector, function (event) {
    (new Alert(this)).close(this);
});
<div class="alert alert-warning alert-dismissible fade show" role="alert">
    <strong>Holy guacamole!</strong> You should check in on some of those fields below.
    <button type="button" class="close" data-dismiss="alert" aria-label="Close">
        <span aria-hidden="true">&times;</span>
    </button>
</div>

本项目引用的自定义外部资源