如何用纯JS制作tabs?

How to make tabs with pure JS?

我正在尝试只用纯 JS CSS 和 HTML 做一个 "tab" 菜单,基本上我有 7 div 内容和 7 "buttons" 应该打开匹配 div。我想使用的策略是将所有具有 "hidden" 或 "Display: none" 属性的 div 堆叠在同一位置,然后,当我单击按钮时,它会变成将 div 匹配到可见。我面临的问题是如何告诉按钮 div 它应该打开(使用数组而不是手动操作),以及当我单击其他 div 时如何将其设置回不可见状态(我正在考虑一个 if(),如果所选按钮的编号与 div 的编号匹配,它只会打开可见性,但据说每个按钮都有一个 div,所以我很困惑)。

我想你想要这样的东西?

document.addEventListener('click', ({ target: { dataset: { id = '' }}}) => {
  if (id.length > 0) {
    document.querySelectorAll('.tab').forEach(t => t.classList.add('hidden'));
    document.querySelector(`#${id}`).classList.remove('hidden');
  }
});
.hidden {
  display:none;
}
<button data-id="tab1">tab 1</button>
<button data-id="tab2">tab 2</button>
<div id="tab1" class="tab">Tab 1</div>
<div id="tab2" class="tab hidden">Tab 2</div>

但现实情况是我们可能不想实际使用 button。 所以让我们改变一下。

const tabClick = ({ target }) => {
    const { dataset: { id = '' }} = target;
    document.querySelectorAll('.tab').forEach(t => t.classList.remove('selected'));
    target.classList.add('selected');
    document.querySelectorAll('.tab-panel').forEach(t => t.classList.add('hidden'));
    document.querySelector(`#${id}`).classList.remove('hidden');
};

const bindTabs = () => {
  document.querySelectorAll('.tab').forEach(tab => {
    tab.addEventListener('click', tabClick);
  })
};

// Belts and braces, lets ensure our DOM is loaded and only assign click to the `tabs`
document.addEventListener('DOMContentLoaded', () => {
  bindTabs();
});
.tab {
  display: inline-block;
  background-color: grey;
  padding: 0.75rem;
  color: #fff;
}

.selected {
  background-color: black;
}

.tab-panel {
  
  border: 2px solid black;
  min-height: 50px;
  max-width: 250px;
  padding: 1rem;
}

.hidden {
  display:none;
}
<div data-id="tab1" class="tab selected">tab 1</div>
<div data-id="tab2" class="tab">tab 2</div>
<div data-id="tab3" class="tab">tab 3</div>
<div data-id="tab4" class="tab">tab 4</div>
<div id="tab1" class="tab-panel">Tab 1</div>
<div id="tab2" class="tab-panel hidden">Tab 2</div>
<div id="tab3" class="tab-panel hidden">Tab 3</div>
<div id="tab4" class="tab-panel hidden">Tab 4</div>

那么我们如何用 basic javascript 来解决这个问题。

const tabCount = 4; // If we add a new tab, increase.

const tabClick = (event) => {
    const tabButtonClicked = event.target;
    const id = event.target.dataset.id;
    
    // First remove selected and hide all tabs
    for(let i = 1; i <= tabCount; i++) {
      let tabButtonID = "#tabButton" + i;
      let tabButton = document.querySelector(tabButtonID);
      let tabID = "#" + tabButton.dataset.id;
      let tab = document.querySelector(tabID);
      tabButton.classList.remove("selected");
      tab.classList.add("hidden");
    }
    
    // Now we set selected and show the selected tab.
    document.querySelector("#" + id).classList.remove("hidden");
    tabButtonClicked.classList.add("selected");
};

const bindTabs = () => {
  // Loop through number of tabs and add a click event.
  for(let i = 1; i <= tabCount; i++) {
    let tabButtonID = "#tabButton" + i;
    let tabButton = document.querySelector(tabButtonID);
    tabButton.addEventListener('click', tabClick);
  }
};

// Belts and braces, lets ensure our DOM is loaded and only assign click to the `tabs`
document.addEventListener('DOMContentLoaded', () => {
  bindTabs();
});
.tab {
  display: inline-block;
  background-color: grey;
  padding: 0.75rem;
  color: #fff;
}

.selected {
  background-color: black;
}

.tab-panel {
  
  border: 2px solid black;
  min-height: 50px;
  max-width: 250px;
  padding: 1rem;
}

.hidden {
  display:none;
}
<div id="tabButton1" data-id="tab1" class="tab selected">tab 1</div>
<div id="tabButton2" data-id="tab2" class="tab">tab 2</div>
<div id="tabButton3" data-id="tab3" class="tab">tab 3</div>
<div id="tabButton4" data-id="tab4" class="tab">tab 4</div>
<div id="tab1" class="tab-panel">Tab 1</div>
<div id="tab2" class="tab-panel hidden">Tab 2</div>
<div id="tab3" class="tab-panel hidden">Tab 3</div>
<div id="tab4" class="tab-panel hidden">Tab 4</div>