Closed2

STUDIOカスタムコードでタブを実現する

miyaponmiyapon

事前にclassを付与できないので、地味に面倒くさいためメモ。
ネーミング雑なので、他のカスタムコードを併用する場合はネームスコープつけたい。

index
<div id="tab-container">
      <div>
        <button id="tab1">Tab 1</button>
        <button id="tab2">Tab 2</button>
        <button id="tab3">Tab 3</button>
      </div>
      <div id="tab-contents">
        <div id="content1">Content 1</div>
        <div id="content2">Content 2</div>
        <div id="content3">Content 3</div>
      </div>
    </div>

classを後付けで見た目を変化させる。左右に少しだけアニメーションさせたい。

style
      #tab-contents > * {
        display: none;
      }
      #tab-contents > *.active-tab {
        display: block;
      }
      #tab-container .active-button {
        color: #black;
        border-bottom-color: red;
      }
      .slide-left {
        animation: slideLeft 0.6s ease-in-out;
      }
      .slide-right {
        animation: slideRight 0.6s ease-in-out;
      }

      @keyframes slideLeft {
        from {
          opacity: 0;
          transform: translateX(20px);
        }
        to {
          opacity: 1;
          transform: translateX(0);
        }
      }

      @keyframes slideRight {
        from {
          opacity: 0;
          transform: translateX(-20px);
        }
        to {
          opacity: 1;
          transform: translateX(0);
        }
      }

loopの回数とタブの個数が合致する必要あり。

script
      document.addEventListener("DOMContentLoaded", function () {
        let activeTabIndex = 1;

        for (let i = 1; i <= 3; i++) {
          let tab = document.getElementById("tab" + i);
          let content = document.getElementById("content" + i);

          if (tab && content) {
            tab.addEventListener("click", function () {
              for (let j = 1; j <= 3; j++) {
                let otherTab = document.getElementById("tab" + j);
                let otherContent = document.getElementById("content" + j);

                if (otherTab && otherContent) {
                  otherTab.classList.remove("active-button");
                  otherContent.classList.remove(
                    "active-tab",
                    "slide-left",
                    "slide-right"
                  );
                }
              }
              this.classList.add("active-button");

              if (i > activeTabIndex) {
                content.classList.add("slide-left");
              } else {
                content.classList.add("slide-right");
              }
              activeTabIndex = i;

              content.classList.add("active-tab");
            });
          }
        }
      });
miyaponmiyapon

カスタムコードを実際に使ったら沼った。
loadする必要ないのね。

最終的にこうなった。

index.js
function setupTabListener(tab, content, index, activeTabIndex) {
  tab.addEventListener("click", function () {
    for (let j = 1; j <= 7; j++) {
      let otherTab = document.getElementById("tab" + j);
      let otherContent = document.getElementById("content" + j);
      if (otherTab && otherContent) {
        otherTab.classList.remove("active-button");
        otherContent.classList.remove("active-tab", "slide-left", "slide-right");
      }
    }

    tab.classList.add("active-button");

    if (index > activeTabIndex.value) {
      content.classList.add("slide-left");
    } else {
      content.classList.add("slide-right");
    }
    activeTabIndex.value = index;

    content.classList.add("active-tab");
  });
}

function initializeTabSwitching() {
  let activeTabIndex = { value: 1 };

  for (let i = 1; i <= 7; i++) {
    let tab = document.getElementById("tab" + i);
    let content = document.getElementById("content" + i);
    if (tab && content) {
      setupTabListener(tab, content, i, activeTabIndex);
    }
  }
  // 初期状態で tab1 と content1 をアクティブにする
  let initialTab = document.getElementById("tab1");
  let initialContent = document.getElementById("content1");
  if (initialTab && initialContent) {
    initialTab.classList.add("active-button");
    initialContent.classList.add("active-tab");
  }
}

initializeTabSwitching();
このスクラップは1ヶ月前にクローズされました