diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 82dec697c2deddf9acd75669125809533ddc0ac5..351675412f07e5ad557cced08ebba67349fcf665 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 0000000000000000000000000000000000000000..fbe82c2fef516892596db2d21b2ccb550f6d4fd5 --- /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); + }); + } + })(); + `, + }, + ], + }; + }, + }; +};