v0.13.0: 前台导航修复(loader 服务函数化防客户端退化)、全站图片占位图+懒加载、favicon、分页圆点、导航 1400px 居中、缺失图片补齐脚本

This commit is contained in:
bigcode
2026-11-04 10:30:16 +08:00
parent 4fba80a216
commit 7fd9e75887
28 changed files with 599 additions and 208 deletions
+27 -1
View File
@@ -39,15 +39,41 @@ export const getLayoutData = createServerFn({ method: "GET" }).handler(async ():
return { menu, footerMenu, categories: cats, footerDoc } satisfies LayoutData;
});
/** # 常量 全站图片懒加载脚本(SSR 直出的 HTML 里 WP 图片多数已带 loading=lazy;
* 专管手工组件/用户编辑图片不带 lazy 的情况):
* - 未带 loading 属性的 <img> 全部补 loading="lazy" + decoding="async"
* - MutationObserver 覆盖后续新增节点
* - 加载失败兜底占位图(CSS 灰底占位背景在 img 未加载时可见)
*/
const LAZY_IMG_SCRIPT = `(function(){
var fix = function(root){
root.querySelectorAll && root.querySelectorAll('img').forEach(function(img){
if (img.hasAttribute('loading') || img.closest('header')) return;
img.setAttribute('loading','lazy');
if (!img.hasAttribute('decoding')) img.setAttribute('decoding','async');
});
};
var boot = function(){
fix(document);
new MutationObserver(function(muts){
for (var m of muts) for (var n of m.addedNodes) if (n.nodeType===1) fix(n);
}).observe(document.body,{childList:true,subtree:true});
};
document.readyState==='loading' ? document.addEventListener('DOMContentLoaded',boot) : boot();
})();`;
/** # 类型 Layout 属性 */
export function Layout(props: { layout: LayoutData; children: React.ReactNode }) {
return (
<>
<Header menu={props.layout.menu} />
<main>{props.children}</main>
{/* ds-site 前台标识:全局 img 占位图/懒加载样式按此作用域(不影响后台) */}
<main className="ds-site">{props.children}</main>
<Footer categories={props.layout.categories} menu={props.layout.footerMenu} doc={props.layout.footerDoc} />
{/* 全局询价弹窗:接管页面内所有 Elementor popup 1129 链接(Make an Inquiry / 按钮) */}
<InquiryPopup />
{/* 全站图片懒加载兜底脚本(绕过 React 水合,直接 setAttribute) */}
<script dangerouslySetInnerHTML={{ __html: LAZY_IMG_SCRIPT }} />
</>
);
}