javascript全局加载遮罩通过一次创建fixed定位dom元素实现,用计数器控制显隐避免闪烁,封装withloading函数自动管理promise生命周期,并支持文字提示与多实例隔离。

在 JavaScript 中实现全局加载中遮罩层(Loading Overlay),核心是用一个 DOM 元素覆盖整个视口,并通过 JS 控制其显示/隐藏。关键在于“全局”和“可控”——它要能被任意业务逻辑调用,且不干扰当前页面结构和交互逻辑。
1. 创建遮罩层 DOM 结构(一次初始化)
遮罩层应只创建一次,挂载到 document.body 底部,避免影响原有布局层级。推荐用内联样式初始化,减少 CSS 依赖:
const createOverlay = () => {
if (document.getElementById('global-loading-overlay')) return;
const overlay = document.createElement('div');
overlay.id = 'global-loading-overlay';
overlay.style.cssText = `
position: fixed;
top: 0; left: 0; right: 0; bottom: 0;
background: rgba(0, 0, 0, 0.4);
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
pointer-events: none;
opacity: 0;
transition: opacity 0.2s;
`;
const spinner = document.createElement('div');
spinner.innerHTML = ' '; // 或插入 SVG / 字符如 '●'
spinner.style.cssText = `
width: 40px; height: 40px;
border: 4px solid #fff;
border-top-color: transparent;
border-radius: 50%;
animation: spin 1s linear infinite;
`;
// 注入简易旋转动画(可选)
const style = document.createElement('style');
style.textContent = `@keyframes spin { to { transform: rotate(360deg); } }`;
document.head.appendChild(style);
overlay.appendChild(spinner);
document.body.appendChild(overlay);
};
createOverlay();
2. 封装显示与隐藏方法(支持嵌套调用)
实际使用中常出现“多个请求同时触发 loading”,需避免重复 show/hide 导致闪烁或状态错乱。用计数器方式管理更稳妥:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
let loadingCount = 0;
const overlay = document.getElementById('global-loading-overlay');
const showLoading = () => {
if (loadingCount === 0) {
overlay.style.opacity = '1';
overlay.style.pointerEvents = 'auto';
}
loadingCount++;
};
const hideLoading = () => {
if (loadingCount > 0) {
loadingCount--;
if (loadingCount === 0) {
overlay.style.opacity = '0';
setTimeout(() => {
if (loadingCount === 0) {
overlay.style.pointerEvents = 'none';
}
}, 200); // 匹配 transition 时间
}
}
};
- 每次
showLoading()都增加计数,只有首次调用才真正显示 - 每次
hideLoading()减一,仅当归零时才真正隐藏 -
pointer-events: none/auto确保遮罩层不拦截点击,但启用时可阻止用户操作
3. 在异步操作中自动控制(推荐配合 Promise 使用)
把 loading 控制逻辑封装进工具函数,让业务代码更干净:
const withLoading = async (promise) => {
showLoading();
try {
const result = await promise;
return result;
} finally {
hideLoading();
}
};
// 使用示例:
document.getElementById('submit-btn').addEventListener('click', async () => {
await withLoading(fetch('/api/data').then(r => r.json()));
// 加载完成,自动关闭遮罩
});
-
finally确保无论成功失败都收尾,防止 loading 残留 - 也可扩展为支持 AbortController、超时、错误重试等场景
- 若用 Axios,可在 request / response interceptor 中统一注入
4. 可选增强:支持文字提示与多实例隔离
简单遮罩有时需要显示“加载中…”或区分不同模块的 loading 状态:
- 给遮罩层加一个
<div class="loading-text"> 子元素,通过 <code>overlay.dataset.text = '提交中...'动态更新 - 如需多个独立遮罩(如弹窗内局部 loading),可改用 class + data 属性标识作用域,配合 querySelector 精准控制
- 移动端注意添加
touch-action: none防止遮罩层干扰手势










