Bootstrap 的 alert 只提供了 fade 方式,如果我们想改变 alert 的移除样式,比如用 slideUp 方式,该如何设置呢?
首先来看看 Bootstrap alert 的 Dismissing,官网的例子是:
<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">×</span>
</button>
</div>
Bootstrap 默认提供了 fade 来增加 alert 的移除效果,如果要改成别的移除样式,就很麻烦,这是为什么呢?
理论上,只要不在 class 里加上 fade,然后自己在 js 里写 $(".alert").slideUp("slow");
就可以了。但结果是,alert 在 slideUp 的效果结束后瞬间又出现了,即使添加了一个 style="display: none"
。麻烦就在于,bootstrap 提供了专门的 triggers 来手动关闭 alert,用普通的元素删除指令是无法删除 alert 的,slideUp 只提供了移除的样式,而 .alert(‘close’) 才是真正将 alert 从页面移除的指令。
所以,我们只需要在 slideUp 后调用 .alert(‘close’) 来彻底删除 alert。但仅仅把这两条命令写在一起就可以了吗?问题没那么简单。
因为 slideUp 是一个渐变的效果,是有延迟的,虽然两句话一前一后看起来有顺序,但是 javascript 是单线程的,命令是同步运行的,后一句并不会等到上一句执行结束才会开始,程序的同步运行是会不停往下跑的。所以,如果单单把两句话一前一后写在一起,结果就是 alert 会直接消失,没有 slideUp 的效果。
因此,最简单的方法,就是设置一个 setTimeout 让 .alert(‘close’) 等到 slideUp 结束再执行,slideUp(“slow”) 执行时间是 600ms,所以只要设置 600ms 的延迟就行了。
还有一个更高级也更麻烦的用法,就是通过 Promise 对象来实现异步,参考阮一峰的《ECMAScript 6》。
最后,再用 setTimeout 来模拟 3 秒后自动通过点击 x 来关闭 alert 框来实现自动消失。
代码如下
<% if alert %>
<div class="alert alert-danger alert-dismissible d-flex justify-content-center" role="alert">
<button type="button" class="close js-alert-close" daria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h5><%= alert %></h5>
</div>
<% end %>
- 注:别忘了删除 button 的
data-dismiss="alert"
if($(".alert").length > 0){
setTimeout(function(){
$(".alert").find(".js-alert-close").click();
}, 3000);
}
$(".js-alert-close").click(function(){
$alert = $(this).closest(".alert");
$alert.slideUp("slow");
setTimeout(function(){
$alert.alert('close');
}, 600);
// let promise = new Promise(function(resolve, reject){
// $alert.slideUp("slow");
// setTimeout(function(){
// resolve();
// }, 600);
// })
// promise.then(function(){
// $alert.alert('close');
// })
});