0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Bootstrap5での話

qiitaやgoogleの、よくある感じのアカウントメニューを楽して作りたい。

image.png

とりあえずtoastで作っても、「外側をクリックしたら閉じる」という実装は自分でやらなきゃならなかった。
よくやりそうなことなので共有:ghost:

実際の動き Fiddle

2024-06-12_00h07_53.gif

コード

  • 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>

他にいい方法があるのでは?

こんなことをわざわざ実装しなきゃいけないのは変な気もする。
いい方法を知ってる人がいたら教えてください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?