シンプルなjavascriptトグルdiv関数

Aug 15 2020

別のメニューでdivをトリガーするコードを作成しました。どちらが優れているのかわかりません。フィードバックをいただけますか?

1つの関数の最初のコード:

function sidebar() {
var menu = document.querySelector('#sidebar-container');
      var menuSmall = document.querySelector('#sidebar-container2');
      var icon = document.getElementById('right');
      menuSmall.style.display = "block";
      menu.style.display = "none";
      if(menu.style.display == "none") {
        icon.onclick = function () {
          menu.style.display = "block";
          menuSmall.style.display = "none";
}
}

2つの関数を持つが同じ動作をする2番目のコード:

function sidebar() {
      var menu = document.querySelector('#sidebar-container');
      var menuSmall = document.querySelector('#sidebar-container2');
      menuSmall.style.display = "block";
      menu.style.display = "none";
        
    },
    function openbar() {
      var menu = document.querySelector('#sidebar-container');
      var menuSmall = document.querySelector('#sidebar-container2');
      menuSmall.style.display = "none";
      menu.style.display = "block";
    }

回答

3 LucasWauke Aug 19 2020 at 09:57

エッジケースについて考える必要がなければ、状態の変化を記述して理解する方が簡単だと思います。

最初のケースでは、すでに必要な状態で開始しており、両方の状態を反転するだけで済みます。2つ目は、すべての状態を「オフ」にして、必要な状態を「オン」にするだけです。

このように考えると、もっと簡単だと思います。

2つのサイドバー

DOMTokenList.toggle()を使用できると思います:

const sidebars = document.querySelectorAll('.sidebar');
const icon = document.getElementById('icon');

const toggle = el => el.classList.toggle('hidden');

icon.addEventListener('click',() => sidebars.forEach(toggle));
/* the display value of a div is block by default */
.hidden {
  display: none;
}
<!-- you don't need to find which sidebar is open in your js -->
<div class="sidebar">first</div>
<div class="sidebar hidden">second</div>
<span id="icon">icon</span>

ドキュメント:

  • DOMTokenList
  • Element.classList
  • DOMTokenList.forEach()

2つ以上のサイドバー

この場合、トグルは役に立たないかもしれません。しかし、私はデータセットが役立つかもしれないと思います

const sidebars = document.querySelectorAll('.sidebar');
const btns = document.querySelectorAll('.btn');

const getSidebar = btn => btn.dataset.sidebar;

const hide = el => el.classList.add('hidden');

btns.forEach(btn =>
  btn.addEventListener('click', () => {
    const target = document.getElementById(getSidebar(btn));
    sidebars.forEach(hide);
    target.classList.remove('hidden');
  })
);
.hidden {
  display: none;
}
<div class="sidebar" id="first">sidebar 1</div>
<div class="sidebar hidden" id="second">sidebar 2</div>
<div class="sidebar hidden" id="third">sidebar 3</div>
<button class="btn" data-sidebar="first">1</button>
<button class="btn" data-sidebar="second">2</button>
<button class="btn" data-sidebar="third">3</button>


1 gyfchong Aug 18 2020 at 18:53

2つの方法から選択する必要がある場合は、2番目の方法を使用します。

読みやすさ、および単一責任の原則の側面で常に誤りを犯す必要があります。

ただし、元のコードの代替案を提案する場合は、CSSクラスの使用を提案します。

function toggleMenu(selectedMenu) {
  // Grab the currently open menu
  var openMenu = document.querySelector('.js-menu-open');
  
  // Grab the menu you want to open
  var targetMenu = document.querySelector(selectedMenu);

  // Scenario 1: a menu is already open
  // Close the open menu.
  if(openMenu) {
    openMenu.classList.replace('js-menu-open', 'js-menu-closed');
  }
  
  // Secnario 2: if the menu you are trying to open isn't the currently open menu
  // Open the target menu.
  if(openMenu !== targetMenu) {
    targetMenu.classList.replace('js-menu-closed', 'js-menu-open');
  }
  
}
.js-menu-closed {
  display: none;
}

.js-menu-open {
  display: block;
}
<div id="sidebar-container" class="js-menu-closed">
  Sidebar 1
</div>

<div id="sidebar-container2" class="js-menu-closed">
  Sidebar 2
</div>

<div id="sidebar-container3" class="js-menu-closed">
  Sidebar 3
</div>

<button onclick="toggleMenu('#sidebar-container')">Toggle sidebar 1</button>
<button onclick="toggleMenu('#sidebar-container2')">Toggle Sidebar 2</button>
<button onclick="toggleMenu('#sidebar-container3')">Toggle sidebar 3</button>

このメソッドは基本的にCSSクラスを一種の永続的な状態として使用します。これにより、JSロジックが簡素化され、コードの繰り返しが減り(DRYのまま)、必要な数のメニューで無限に再利用できます。:)

その他の利点は、メニューのいずれかをデフォルトで開いて、CSSでよりパフォーマンスの高いアニメーションを適用できるようになったことです。

これがお役に立てば幸いです。