睿能科技
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

170 lines
5.1 KiB

import "./common.js";
//#region js/product.js
function setActiveNav() {
const pageNav = document.querySelector("[data-nav]")?.getAttribute("data-nav");
if (!pageNav) return;
document.querySelectorAll(".site-header__nav a").forEach((link) => {
const active = link.textContent.trim().startsWith(pageNav);
link.classList.toggle("is-active", active);
});
}
function introGalleryInit() {
const root = document.querySelector(".p-intro__gallery");
if (!root || !window.Swiper) return;
const swiper = new window.Swiper(root, {
loop: true,
speed: 500,
autoplay: {
delay: 3e3,
disableOnInteraction: false
},
observer: true,
observeParents: true,
resizeObserver: true,
pagination: {
el: ".p-intro__gallery-pagination",
clickable: true
}
});
window.addEventListener("resize", () => swiper.update(), { passive: true });
}
function relatedCarouselInit() {
const root = document.querySelector(".p-related");
const el = root?.querySelector(".p-related__swiper");
if (!root || !el || !window.Swiper) return;
const slideCount = el.querySelectorAll(".swiper-wrapper > .swiper-slide").length;
// 一屏展示 4 条,不超过 4 条时隐藏切换按钮
if (slideCount <= 4) {
root.querySelectorAll(".p-related__header .s-arrows").forEach((node) => {
node.style.display = "none";
});
}
new window.Swiper(el, {
slidesPerView: 1.15,
spaceBetween: 16,
grabCursor: true,
watchOverflow: true,
pagination: {
el: root.querySelector(".p-related__pagination"),
clickable: true
},
navigation: {
nextEl: root.querySelector(".s-arrows__next"),
prevEl: root.querySelector(".s-arrows__prev")
},
breakpoints: {
768: {
slidesPerView: 2,
spaceBetween: 24
},
1200: {
slidesPerView: 4,
spaceBetween: 40
}
}
});
}
function productSubnavInit() {
const subnav = document.querySelector("[data-p-subnav]");
const intro = document.querySelector("#p-intro");
if (!subnav || !intro) return;
const sectionIds = [
"p-intro",
"p-spec",
"p-download",
"p-related"
];
const sections = sectionIds.map((id) => document.getElementById(id)).filter(Boolean);
const links = [...subnav.querySelectorAll("[data-p-nav]")];
const setVisible = (visible) => {
subnav.classList.toggle("is-visible", visible);
subnav.setAttribute("aria-hidden", visible ? "false" : "true");
document.body.classList.toggle("is-p-subnav", visible);
};
const setActiveLink = (id) => {
links.forEach((link) => {
link.classList.toggle("is-active", link.dataset.pNav === id);
});
};
const getSubnavHeight = () => subnav.offsetHeight || 80;
const updateActiveByScroll = () => {
const offset = getSubnavHeight() + 8;
let current = sectionIds[0];
for (const section of sections) if (section.getBoundingClientRect().top <= offset) current = section.id;
setActiveLink(current);
};
const updateVisibility = () => {
const visible = intro.getBoundingClientRect().top <= 1;
setVisible(visible);
if (visible) updateActiveByScroll();
};
const scrollToSection = (id) => {
const target = document.getElementById(id);
if (!target) return;
const top = window.scrollY + target.getBoundingClientRect().top - getSubnavHeight();
if (window.lenis) window.lenis.scrollTo(top, { duration: 1 });
else window.scrollTo({
top,
behavior: "smooth"
});
};
subnav.addEventListener("click", (event) => {
const link = event.target.closest("[data-p-nav], .p-subnav__cta");
if (!link) return;
if (link.hasAttribute("data-selection-trigger")) return;
const href = link.getAttribute("href");
if (!href || !href.startsWith("#")) return;
event.preventDefault();
scrollToSection(href.slice(1));
});
document.querySelectorAll("a[href=\"#p-spec\"]").forEach((link) => {
if (link.closest("[data-p-subnav]")) return;
if (link.hasAttribute("data-selection-trigger")) return;
link.addEventListener("click", (event) => {
event.preventDefault();
scrollToSection("p-spec");
});
});
const onScroll = () => {
updateVisibility();
};
if (window.lenis) window.lenis.on("scroll", onScroll);
else window.addEventListener("scroll", onScroll, { passive: true });
window.addEventListener("resize", updateVisibility, { passive: true });
updateVisibility();
}
function selectionModalInit() {
const modal = document.querySelector("[data-selection-modal]");
if (!modal) return;
const open = () => {
modal.hidden = false;
document.body.style.overflow = "hidden";
if (window.lenis?.stop) window.lenis.stop();
};
const close = () => {
modal.hidden = true;
document.body.style.overflow = "";
if (window.lenis?.start) window.lenis.start();
};
document.querySelectorAll("[data-selection-trigger]").forEach((trigger) => {
trigger.addEventListener("click", (event) => {
if (trigger.classList.contains("disabled")) return;
event.preventDefault();
open();
});
});
modal.querySelectorAll("[data-selection-close]").forEach((el) => {
el.addEventListener("click", close);
});
document.addEventListener("keydown", (event) => {
if (event.key === "Escape" && !modal.hidden) close();
});
}
$(function() {
setActiveNav();
introGalleryInit();
relatedCarouselInit();
productSubnavInit();
selectionModalInit();
});
//#endregion