//#region \0vite/modulepreload-polyfill.js (function polyfill() { const relList = document.createElement("link").relList; if (relList && relList.supports && relList.supports("modulepreload")) return; for (const link of document.querySelectorAll("link[rel=\"modulepreload\"]")) processPreload(link); new MutationObserver((mutations) => { for (const mutation of mutations) { if (mutation.type !== "childList") continue; for (const node of mutation.addedNodes) if (node.tagName === "LINK" && node.rel === "modulepreload") processPreload(node); } }).observe(document, { childList: true, subtree: true }); function getFetchOpts(link) { const fetchOpts = {}; if (link.integrity) fetchOpts.integrity = link.integrity; if (link.referrerPolicy) fetchOpts.referrerPolicy = link.referrerPolicy; if (link.crossOrigin === "use-credentials") fetchOpts.credentials = "include"; else if (link.crossOrigin === "anonymous") fetchOpts.credentials = "omit"; else fetchOpts.credentials = "same-origin"; return fetchOpts; } function processPreload(link) { if (link.ep) return; link.ep = true; const fetchOpts = getFetchOpts(link); fetch(link.href, fetchOpts); } })(); //#endregion //#region js/common.js const UI_I18N = { zh: { "video.play": "视频播放", "filter.by_product": "按产品筛选", "about.expand_more": "展开更多", "about.collapse": "收起", "brand.short": "睿能科技", "stock.delay_note": "截止 {time}*报价有十五分钟或以上延迟。", "contact.name_required": "请输入姓名", "contact.phone_required": "请输入手机号", "contact.company_required": "请输入公司名称", "contact.email_required": "请输入邮箱", "contact.submitting": "提交中...", "contact.submit": "提交", "contact.success": "提交成功,我们会尽快与您联系!", "contact.fail": "提交失败,请稍后重试", "contact.network_error": "网络错误,请稍后重试", "earth.hq_fuzhou_html": "全球总部
福州" }, en: { "video.play": "Video", "filter.by_product": "Filter by product", "about.expand_more": "Show more", "about.collapse": "Show less", "brand.short": "RAYNEN", "stock.delay_note": "As of {time}* Quotes delayed by 15 minutes or more.", "contact.name_required": "Please enter your name", "contact.phone_required": "Please enter your phone number", "contact.company_required": "Please enter your company name", "contact.email_required": "Please enter your email", "contact.submitting": "Submitting...", "contact.submit": "Submit", "contact.success": "Submitted successfully. We will contact you soon.", "contact.fail": "Submission failed. Please try again later.", "contact.network_error": "Network error. Please try again later.", "earth.hq_fuzhou_html": "Global HQ
Fuzhou" } }; function getUiLang() { const fromHeader = document.querySelector(".site-header__lang")?.getAttribute("data-lang-current"); if (fromHeader === "en" || fromHeader === "zh") return fromHeader; const seg = location.pathname.replace(/^\//, "").split("/")[0] || ""; return seg === "en" ? "en" : "zh"; } function t(key, vars) { const lang = getUiLang(); const table = UI_I18N[lang] || UI_I18N.zh; let str = table[key] ?? UI_I18N.zh[key] ?? key; if (vars && typeof vars === "object") { Object.keys(vars).forEach((k) => { str = str.replace(new RegExp(`\\{${k}\\}`, "g"), String(vars[k])); }); } return str; } window.getUiLang = getUiLang; window.t = t; $(function() { AOS.init({ duration: 800 }); const lenis = new Lenis(); window.lenis = lenis; gsap.registerPlugin(ScrollTrigger, Observer); lenis.on("scroll", ScrollTrigger.update); gsap.ticker.add((time) => { lenis.raf(time * 1e3); }); gsap.ticker.lagSmoothing(0); const $header = $(".site-header"); const $mask = $(".mask"); const $targets = $("[data-header-dark]"); const updateHeader = () => { if (!$header.length) return; const headerRect = $header[0].getBoundingClientRect(); let shouldDark = false; const probeX = Math.max(0, Math.min(window.innerWidth - 1, window.innerWidth / 2)); const probeY = Math.max(0, Math.min(window.innerHeight - 1, headerRect.bottom + 2)); if (document.elementFromPoint(probeX, probeY)?.closest("[data-header-dark]")) shouldDark = true; else $targets.each(function() { const rect = this.getBoundingClientRect(); if (rect.top <= headerRect.bottom && rect.bottom > headerRect.top) { shouldDark = true; return false; } }); $header.toggleClass("dark", shouldDark || $header.hasClass("is-mega-open")); const isScrolled = window.scrollY > 50; $header.toggleClass("is-scrolled", isScrolled); $mask.toggleClass("is-scrolled", isScrolled); }; lenis.on("scroll", updateHeader); ScrollTrigger.addEventListener("refresh", updateHeader); updateHeader(); const maskEl = document.querySelector(".mask"); const maskContentEl = document.querySelector(".mask-content"); function setMaskOpenUi(isOpen) { $("body").toggleClass("is-mask-open", isOpen); } $(".site-header__extra-btn.toggle").on("click", function() { if (!maskEl || !maskContentEl) return; const nodes = maskContentEl.querySelectorAll(".mask-nav__link"); $(maskEl).addClass("show mask--nav-motion"); $("body").css("overflow", "hidden"); setMaskOpenUi(true); gsap.killTweensOf(nodes); gsap.from(nodes, { opacity: 0, y: 10, stagger: .04, delay: .2, overwrite: "auto", onComplete: function() { maskEl.classList.remove("mask--nav-motion"); gsap.set(nodes, { clearProps: "all" }); } }); }); $(".mask-header__icon-btn--close").on("click", function() { if (!maskEl || !maskContentEl) return; gsap.killTweensOf(maskContentEl.querySelectorAll("ul li a")); $(maskEl).removeClass("show mask--nav-motion"); $("body").css("overflow", "auto"); setMaskOpenUi(false); }); $(".mask-nav__toggle").on("click", function() { const $item = $(this).closest(".mask-nav__item--expandable, .mask-nav__subitem--expandable"); const isExpanded = $item.attr("data-expanded") === "true"; $item.attr("data-expanded", String(!isExpanded)); $(this).attr("aria-expanded", String(!isExpanded)); }); // nav-mega 子组:标题 / 箭头均可展开收起(同组互斥) $(document).on("click", ".nav-mega__subgroup-title, .nav-mega__subgroup-toggle", function() { const $subgroup = $(this).closest(".nav-mega__subgroup"); const $siblings = $subgroup.siblings(".nav-mega__subgroup"); const isExpanded = !$subgroup.hasClass("is-expanded"); $siblings.removeClass("is-expanded").find(".nav-mega__subgroup-toggle").attr("aria-expanded", false); $subgroup.toggleClass("is-expanded", isExpanded); $subgroup.find(".nav-mega__subgroup-toggle").attr("aria-expanded", isExpanded); }); // 语言切换:始终跳到对应语言首页(避免详情页等带 id 的 URL 直接换前缀后报错) (function initLangSwitch() { const ALLOWED = ["zh", "tc", "en", "ja", "de", "fa", "id", "th", "ru"]; const defaultLang = document.querySelector(".site-header__lang")?.getAttribute("data-lang-default") || "zh"; const getPathLang = () => { const seg = location.pathname.replace(/^\//, "").split("/")[0] || ""; return ALLOWED.includes(seg) ? seg : defaultLang; }; const buildLangHomeUrl = (targetLang) => { if (!targetLang || targetLang === defaultLang) return "/"; return `/${targetLang}`; }; const goLang = (targetLang) => { if (!targetLang) return; const cur = getPathLang(); const uiCur = cur === "en" ? "en" : "zh"; if (targetLang === uiCur || targetLang === cur) return; location.href = buildLangHomeUrl(targetLang); }; const syncActive = () => { const uiLang = getPathLang() === "en" ? "en" : "zh"; $(".site-header__lang [data-lang]").removeClass("site-header__lang-active"); $(`.site-header__lang [data-lang="${uiLang}"]`).addClass("site-header__lang-active"); }; $(document).on("click", ".site-header__lang [data-lang]", function(e) { e.preventDefault(); e.stopPropagation(); goLang(this.getAttribute("data-lang")); }); $(document).on("click", ".site-header__lang", function(e) { if ($(e.target).closest("[data-lang]").length) return; goLang(getPathLang() === "en" ? "zh" : "en"); }); $(document).on("click", ".site-header__extra-btn.lang, .mask-header__icon-btn.lang", function(e) { e.preventDefault(); goLang(getPathLang() === "en" ? "zh" : "en"); }); syncActive(); })(); // $(".section-contact-form").on("submit", function(e) { // e.preventDefault(); // const $form = $(this); // const $name = $form.find("[name=\"name\"]"); // const $phone = $form.find("[name=\"phone\"]"); // const name = $.trim($name.val()); // const phone = $.trim($phone.val()); // const agreed = $form.find("[name=\"agree\"]").is(":checked"); // if (!name) { // alert("请输入姓名"); // $name.focus(); // return; // } // if (!phone) { // alert("请输入联系方式"); // $phone.focus(); // return; // } // if (!agreed) { // alert("请阅读并同意隐私政策"); // return; // } // alert("提交成功,我们将尽快与您联系"); // $form[0].reset(); // }); $("#nav-mega-product").on("mouseenter", "[data-mega-cat]", function() { const $mega = $("#nav-mega-product"); const cat = $(this).attr("data-mega-cat"); $mega.find("[data-mega-cat]").removeClass("is-active"); $(this).addClass("is-active"); $mega.find("[data-mega-panel]").each(function() { const match = this.dataset.megaPanel === cat; this.hidden = !match; this.classList.toggle("is-active", match); }); }); // Lenis.stop() 会加 .lenis-stopped { overflow: clip },经典滚动条(如360)消失后 // fixed 头部会变宽;内容区通常不变。只补偿头部,不给 html/body 加 padding。 function getScrollbarWidth() { return Math.max(0, window.innerWidth - document.documentElement.clientWidth); } function lockPageScroll() { const root = document.documentElement; if (root.classList.contains("is-scroll-locked")) return; const sbw = getScrollbarWidth(); root.style.setProperty("--scroll-lock-compensation", `${sbw}px`); root.classList.add("is-scroll-locked"); lenis.stop(); // 若 CSS 已保住滚动条,则清零补偿,避免头部被多余收窄 requestAnimationFrame(() => { if (getScrollbarWidth() > 0) { root.style.setProperty("--scroll-lock-compensation", "0px"); } }); } function unlockPageScroll() { const root = document.documentElement; if (!root.classList.contains("is-scroll-locked")) return; root.classList.remove("is-scroll-locked"); root.style.removeProperty("--scroll-lock-compensation"); lenis.start(); } $(".nav-mega").attr("data-lenis-prevent", ""); $(".site-header__nav-item--mega").on("mouseenter", function() { if ($("body").hasClass("is-mask-open")) return; lockPageScroll(); }).on("mouseleave", function() { if ($("body").hasClass("is-mask-open")) return; unlockPageScroll(); }); // 股票行情局部刷新(页脚 + 投资者关系页),不整页 reload (function initStockQuoteRefresh() { const INTERVAL = 60 * 1000; let timer = null; const setText = (el, text) => { if (el) el.textContent = text; }; const setColor = (el, color) => { if (!el) return; if (color) el.style.color = color; else el.style.removeProperty("color"); }; const applyQuote = (data) => { if (!data) return; const color = data.color || ""; const changeText = `${data.change || "--"}\u00a0\u00a0${data.changePercent || "--"}`; document.querySelectorAll("[data-stock-quote]").forEach((root) => { const priceEl = root.querySelector('[data-stock="price"]'); const unitEl = root.querySelector('[data-stock="unit"]'); const changeEl = root.querySelector('[data-stock="change"]'); setText(priceEl, data.price ?? "--"); setText(changeEl, changeText); setColor(priceEl, color); setColor(unitEl, color); setColor(changeEl, color); }); setText(document.querySelector('[data-stock="high"]'), data.high ?? "--"); setText(document.querySelector('[data-stock="low"]'), data.low ?? "--"); setText(document.querySelector('[data-stock="volume"]'), data.volume ?? "--"); setText(document.querySelector('[data-stock="amount"]'), data.amount ?? "--"); const timeEl = document.querySelector('[data-stock="time"]'); if (timeEl && data.updateTime) { timeEl.textContent = t("stock.delay_note", { time: data.updateTime }); } const chartEl = document.querySelector('#stock-chart, [data-stock="chart"]'); if (chartEl) { const code = document.querySelector("[data-stock-quote]")?.getAttribute("data-stock-code") || data.code || "603933"; const market = String(code).charAt(0) === "6" ? "sh" : "sz"; const raw = String(data.chart || `https://image.sinajs.cn/newchart/min/n/${market}${code}.gif`); const base = raw.split("?")[0]; chartEl.setAttribute("src", `${base}?t=${Date.now()}`); } }; const fetchQuote = () => { const code = document.querySelector("[data-stock-quote]")?.getAttribute("data-stock-code") || "603933"; return fetch(`/stock/quote?code=${encodeURIComponent(code)}`, { credentials: "same-origin", headers: { Accept: "application/json" } }) .then((res) => (res.ok ? res.json() : null)) .then((json) => { if (!json || (json.code !== 0 && json.code !== 200)) return; applyQuote(json.data || json); }) .catch(() => {}); }; const start = () => { if (timer) return; timer = setInterval(fetchQuote, INTERVAL); }; const stop = () => { if (!timer) return; clearInterval(timer); timer = null; }; if (!document.querySelector("[data-stock-quote], [data-stock='chart'], #stock-chart")) return; fetchQuote(); start(); document.addEventListener("visibilitychange", () => { if (document.hidden) { stop(); } else { fetchQuote(); start(); } }); })(); }); //#endregion