前提
管理画面を作成していて、行にはメニューボタンがあり、要件は以下の通りです。
- メニューボタンクリックで、その行のメニューが表示(開いているときにクリックすると非表示になる)
- メニューボタン以外の箇所クリックで、全てのメニューが非表示
- メニューが開いているときに、他の行のメニューボタンクリックで、そのメニューは表示されて、もともと表示されていたメニューは非表示
jsで、メニューに.hide
を付けると非表示、外すと表示されるようにしています。
(表示非表示の切り替えはCSSで制御)
困っていること
以下コードで、ちゃんと動いてはいるのですが、行の数が1000とか2000になると、クリックしたときに微妙にタイムラグが生じて、表示非表示の切り替わりが遅れます。
おそらく、hideAll()
で全ての.menu
に対して処理をしているからだとは思うのですが、もっと効率のいい書き方はないでしょうか?
<table> <tr> <td>1</td> <td> <button class="menu-btn">menu</button> <ul class="menu hide"> <li><a>メニュー1</a></li> <li><a>メニュー2</a></li> </ul> </td> </tr> <tr> <td>2</td> <td> <button class="menu-btn">menu</button> <ul class="menu hide"> <li><a>メニュー1</a></li> <li><a>メニュー2</a></li> </ul> </td> </tr> <tr> <td>3</td> <td> <button class="menu-btn">menu</button> <ul class="menu hide"> <li><a>メニュー1</a></li> <li><a>メニュー2</a></li> </ul> </td> </tr> </table>
function toggle(_menuBtn) { const menu = _menuBtn.nextElementSibling; if(menu.classList.contains('hide')){ menu.classList.remove('hide'); } else{ menu.classList.add('hide'); } } function hide(_menuBtn) { const menu = _menuBtn.nextElementSibling; menu.classList.add('hide'); } function hideAll(_clickSelfMenuBtn) { [...document.querySelectorAll('.menu-btn')].forEach(_menuBtn => { if(_clickSelfMenuBtn !== _menuBtn){ hide(_menuBtn); } }); } document.addEventListener('click', (_ev) => { if(!_ev.target.closest('.menu-btn')) { hideAll(); } else { hideAll(_ev.target); toggle(_ev.target); } })
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/08/03 03:32