Bootstrap5での話
qiitaやgoogleの、よくある感じのアカウントメニューを楽して作りたい。
とりあえずtoastで作っても、「外側をクリックしたら閉じる」という実装は自分でやらなきゃならなかった。
よくやりそうなことなので共有
実際の動き Fiddle
コード
- bodyでのクリックハンドラで乱暴にhideすると、開いた瞬間に閉じられる
- showしたとき
once
なハンドラでhideを設定すると、showボタンでのクリックで閉じることができない
従って次のように実装した
const toastElList = document.querySelectorAll('.toast')
const toastList = [...toastElList].map(toastEl => new bootstrap.Toast(toastEl))
// bodyにclickが来たらhide
document.body.addEventListener('click', function (event) {
toastList.forEach(function (toast) {
if (toast.isShown()) {
toast.hide();
}
});
});
// toast上のクリックがbodyに行かないようにする
toastElList.forEach(function (toastEl) {
toastEl.addEventListener("click", function (event) {
event.stopPropagation();
});
});
// onClickに設定するtoast表示関数
function show_toast(event, selector) {
const el = document.querySelector(selector);
const toast = new bootstrap.Toast(el);
if (toast.isShown()) {
// すでに見えてたら何もしない
// 結果的にbodyへのclickとなりtoastがhideされる
}
else {
toast.show();
// このクリック自身でhideしないようにする
event.stopPropagation();
}
}
show_toast(event, selector)
を表示用ボタンのクリックハンドラに設定する。
<button class="btn btn-primary" onclick="show_toast(event, '#my_toast')">ボタン</button>
<div id="my_toast" class="toast">
<!-- toastの内容 -->
</div>
他にいい方法があるのでは?
こんなことをわざわざ実装しなきゃいけないのは変な気もする。
いい方法を知ってる人がいたら教えてください。