TEST-web-siteの5のjsコーディング

TEST 3のコーディングです。デザイン重視のサイトです

jsの「スクロールしたらヘッダーが出現。TOPに戻ったらヘッダー隠し」のnavi.jsの部分

window.addEventListener("scroll", function () {
  const header = document.querySelector(".header_hide");
  if (window.scrollY > 500) {
    header.classList.add("show");
  } else {
    header.classList.remove("show");
  }
});


jsでタッチパネルののhambergerの開閉の部分!!開いたらg-navi出現の部分(g-navi開き中はノースクロール)

/*ハンバーガナビの開閉*/
document.addEventListener("DOMContentLoaded", function () {
  const openBtns = document.querySelectorAll(".openbtn");
  const body = document.body;

  openBtns.forEach(function (openBtn) {
    // openBtnの親header内のg-navまたは#g-navを取得
    const parent = openBtn.closest("header");
    const gNav = parent ? parent.querySelector(".g-nav, #g-nav") : null;
    if (!gNav) return;

    openBtn.addEventListener("click", function (event) {
      event.preventDefault();
      openBtn.classList.toggle("active");
      gNav.classList.toggle("panelactive");
      if (gNav.classList.contains("panelactive")) {
        document.body.classList.add("no-scroll");
        document.documentElement.classList.add("no-scroll");
      } else {
        document.body.classList.remove("no-scroll");
        document.documentElement.classList.remove("no-scroll");
      }
    });

    // ナビゲーション内リンククリックで閉じる
    const navLinks = gNav.querySelectorAll("a");
    navLinks.forEach(function (link) {
      link.addEventListener("click", function (event) {
        event.preventDefault();
        openBtn.classList.remove("active");
        gNav.classList.remove("panelactive");
        document.body.classList.remove("no-scroll");
        document.documentElement.classList.remove("no-scroll");
      });
    });
  });
});


jsでMVのテキスト出現で、1行目と2行目がdelayでフェードインそれも1文字づつ出現

window.addEventListener("DOMContentLoaded", () => {
  const lines = document.querySelectorAll(".mv-title-line");
  // 1行目と2行目で文字の遅延速度を変えたい場合
  const charDelays = [200, 80]; // 1行目:200ms, 2行目:80ms
  const lineDelay = 1000; // 各行の開始遅延
  const afterBoxDelay = 700; // 枠表示後に文字を出すまでの遅延(ms)
  lines.forEach((line, lineIdx) => {
    setTimeout(() => {
      line.classList.add("show");
      const text = line.textContent;
      line.textContent = "";
      text.split("").forEach((char, i) => {
        const span = document.createElement("span");
        span.textContent = char;
        span.className = "mv-title-char";
        line.appendChild(span);
        setTimeout(() => {
          span.classList.add("show");
        }, charDelays[lineIdx] * i + afterBoxDelay);
      });
    }, lineDelay * lineIdx);
  });
});


jsでセクチョンの要素に入ったら、指定の要素がフェードイン(アップやサイドイン)してくるJS

document.addEventListener("DOMContentLoaded", function () {
  // 画像グループ内以外の.fadein-effectを対象
  const allFadein = Array.from(document.querySelectorAll(".fadein-effect"));
  const group = document.querySelector(".product_design_image_group");
  let groupFigures = [];
  if (group) {
    groupFigures = Array.from(group.querySelectorAll(".fadein-effect"));
  }
  const normalFadein = allFadein.filter((el) => !groupFigures.includes(el));

  const observer = new IntersectionObserver(
    (entries, obs) => {
      entries.forEach((entry) => {
        if (entry.isIntersecting) {
          entry.target.classList.add("is-visible");
          obs.unobserve(entry.target);
        }
      });
    },
    { threshold: 0.2 }
  );
  normalFadein.forEach((item) => observer.observe(item));
});


jsでセクチョンの要素に入ったら、指定の要素が順番にフェードイン(アップやサイドイン)してくるJS

document.addEventListener("DOMContentLoaded", function () {
  const group = document.querySelector(".product_design_image_group");
  if (group) {
    const figures = group.querySelectorAll(".fadein-effect");
    const groupObserver = new IntersectionObserver(
      (entries, obs) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting) {
            figures.forEach((fig, i) => {
              setTimeout(() => {
                fig.classList.add("is-visible");
              }, i * 400); // 0.4秒ずつ遅延
            });
            obs.unobserve(entry.target);
          }
        });
      },
      { threshold: 0.2 }
    );
    groupObserver.observe(group);
  }
});


jsでオススメ商品のカードをnext.prevで一つづつ移動し、尚且つ最後まで行ったらループ。先頭のカードは真ん中位置からスタートのJS(ダブルタップ禁止とスワイプでカード移動できる)

document.addEventListener("DOMContentLoaded", function () {
  const itemsContainer = document.querySelector(".product_recomend_items");
  const items = document.querySelectorAll(".product_recomend_item");
  const prevBtn = document.querySelector(".carousel-prev");
  const nextBtn = document.querySelector(".carousel-next");
  const wrapper = document.querySelector(".recomend_product_wrapper");
  if (!itemsContainer || !items.length || !prevBtn || !nextBtn || !wrapper)
    return;

  let currentIndex = 0;
  const gap = 50;
  const visibleCount = 1;
  const maxIndex = items.length - visibleCount;

  let itemWidth = items[0].offsetWidth;
  let wrapperWidth = wrapper.offsetWidth;
  let sidePadding = (wrapperWidth - itemWidth) / 2;
  let slideWidth = itemWidth + gap;

  function setPaddingAndSlideWidth() {
    itemWidth = items[0].offsetWidth;
    wrapperWidth = wrapper.offsetWidth;
    sidePadding = (wrapperWidth - itemWidth) / 2;
    slideWidth = itemWidth + gap;
    itemsContainer.style.paddingLeft = sidePadding + "px";
    itemsContainer.style.paddingRight = sidePadding + "px";
  }

  function updateCarousel() {
    itemsContainer.style.transform = `translateX(${
      -currentIndex * slideWidth
    }px)`;
  }

  prevBtn.addEventListener("click", function () {
    if (currentIndex > 0) {
      currentIndex--;
    } else {
      currentIndex = maxIndex;
    }
    updateCarousel();
  });

  nextBtn.addEventListener("click", function () {
    if (currentIndex < maxIndex) {
      currentIndex++;
    } else {
      currentIndex = 0;
    }
    updateCarousel();
  });

  // ダブルタップによるズーム防止
  let lastTouch = 0;
  [prevBtn, nextBtn].forEach((btn) => {
    btn.addEventListener("touchend", function (e) {
      const now = Date.now();
      if (now - lastTouch <= 300) {
        e.preventDefault();
      }
      lastTouch = now;
    });
  });

  // スワイプ操作対応
  let touchStartX = 0;
  let touchEndX = 0;
  let isSwiping = false;
  const swipeThreshold = 50; // スワイプ判定の閾値(px)

  wrapper.addEventListener("touchstart", function (e) {
    if (e.touches.length === 1) {
      touchStartX = e.touches[0].clientX;
      isSwiping = true;
    }
  });

  wrapper.addEventListener("touchmove", function (e) {
    if (!isSwiping) return;
    touchEndX = e.touches[0].clientX;
  });

  wrapper.addEventListener("touchend", function (e) {
    if (!isSwiping) return;
    const diffX = touchEndX - touchStartX;
    if (Math.abs(diffX) > swipeThreshold) {
      if (diffX < 0) {
        // 左スワイプ(次へ)
        if (currentIndex < maxIndex) {
          currentIndex++;
        } else {
          currentIndex = 0;
        }
        updateCarousel();
      } else if (diffX > 0) {
        // 右スワイプ(前へ)
        if (currentIndex > 0) {
          currentIndex--;
        } else {
          currentIndex = maxIndex;
        }
        updateCarousel();
      }
    }
    isSwiping = false;
    touchStartX = 0;
    touchEndX = 0;
  });

  // ウィンドウリサイズ時も中央寄せを維持
  window.addEventListener("resize", function () {
    setPaddingAndSlideWidth();
    updateCarousel();
  });

  // 初期化
  setPaddingAndSlideWidth();
  updateCarousel();
});


サイトは

こちらから