From 62369277576419317dc1c77d5f2024d2e2d3c9d9 Mon Sep 17 00:00:00 2001 From: linyingxue Date: Thu, 17 Apr 2025 16:50:23 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=8E=A5=E5=8F=A3=E6=96=87=E6=A1=A3API?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E6=B7=BB=E5=8A=A0loading=E5=8A=A0=E8=BD=BD?= =?UTF-8?q?=E6=95=88=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docusaurus.config.ts | 2 + src/plugins/scalar-loading-plugin.js | 145 +++++++++++++++++++++++++++ 2 files changed, 147 insertions(+) create mode 100644 src/plugins/scalar-loading-plugin.js diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 82dec69..3516754 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -248,6 +248,8 @@ const config: Config = { } satisfies Preset.ThemeConfig, plugins: [ 'docusaurus-plugin-image-zoom', + // 添加自定义加载效果插件 + require('./src/plugins/scalar-loading-plugin'), [ '@scalar/docusaurus', { diff --git a/src/plugins/scalar-loading-plugin.js b/src/plugins/scalar-loading-plugin.js new file mode 100644 index 0000000..fbe82c2 --- /dev/null +++ b/src/plugins/scalar-loading-plugin.js @@ -0,0 +1,145 @@ +/** + * 向Scalar API Reference添加加载效果的自定义插件 + */ +module.exports = function () { + return { + name: 'scalar-loading-plugin', + injectHtmlTags() { + return { + headTags: [ + { + tagName: 'style', + attributes: { + type: 'text/css', + }, + innerHTML: ` + /* Scalar API Reference 加载效果 */ + .scalar-loading-indicator { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + background-color: rgba(255, 255, 255, 0.8); + z-index: 9999; + transition: opacity 0.3s ease; + } + + .scalar-loading-spinner { + width: 50px; + height: 50px; + border: 5px solid #f3f3f3; + border-top: 5px solid var(--ifm-color-primary-light); + border-radius: 50%; + animation: spinner 1s linear infinite; + } + + .scalar-loading-text { + margin-top: 20px; + font-size: 14px; + color: var(--ifm-color-gray-700); + } + + @keyframes spinner { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } + } + + [data-theme='dark'] .scalar-loading-indicator { + background-color: rgba(2, 8, 23, 0.8); + } + + [data-theme='dark'] .scalar-loading-spinner { + border-color: var(--ifm-color-gray-700); + border-top-color: var(--ifm-color-primary); + } + `, + }, + ], + postBodyTags: [ + { + tagName: 'script', + innerHTML: ` + (function() { + // 检查是否在API文档页面 + if (window.location.pathname.includes('/docs/openapi/')) { + // 创建加载指示器 + const loadingIndicator = document.createElement('div'); + loadingIndicator.className = 'scalar-loading-indicator'; + loadingIndicator.id = 'scalar-loading-indicator'; + + const spinner = document.createElement('div'); + spinner.className = 'scalar-loading-spinner'; + + const text = document.createElement('div'); + text.className = 'scalar-loading-text'; + text.textContent = '正在加载中...'; + + loadingIndicator.appendChild(spinner); + loadingIndicator.appendChild(text); + + // 添加到body + document.body.appendChild(loadingIndicator); + + // 监控页面加载完成 + window.addEventListener('load', function() { + // 监听Scalar容器加载完成 + const checkScalarLoaded = setInterval(function() { + // 针对不同的页面检查不同的选择器 + const selectors = [ + '.scalar-api-reference', // v1 API页面 + '[data-scalar-api-reference]' // 备用选择器 + ]; + + let isLoaded = false; + + for (const selector of selectors) { + const container = document.querySelector(selector); + if (container && (container.children.length > 0 || container.shadowRoot)) { + isLoaded = true; + break; + } + } + + if (isLoaded) { + // 内容已加载,淡出加载指示器 + loadingIndicator.style.opacity = '0'; + + // 动画结束后移除元素 + setTimeout(() => { + document.body.removeChild(loadingIndicator); + }, 300); + + clearInterval(checkScalarLoaded); + } + }, 100); + + // 超时处理(20秒后仍未加载完成) + setTimeout(function() { + if (document.getElementById('scalar-loading-indicator')) { + loadingIndicator.style.opacity = '0'; + + // 动画结束后移除元素 + setTimeout(() => { + if (document.getElementById('scalar-loading-indicator')) { + document.body.removeChild(loadingIndicator); + } + }, 300); + + clearInterval(checkScalarLoaded); + } + }, 20000); + }); + } + })(); + `, + }, + ], + }; + }, + }; +}; -- Gitee