原生 js - showLoading 显示加载中
loading
参数
textOrOptions
: string | Object - 加载提示文本或配置选项options
: Object - 配置选项text
: string - 加载提示文本,默认'加载中...'fullscreen
: boolean - 是否全屏显示,默认 truebackground
: string - 遮罩背景色,默认'rgba(0, 0, 0, 0.7)'target
: HTMLElement - 遮罩挂载的目标元素,在非全屏模式下生效lock
: boolean - 是否锁定屏幕滚动,默认 false
返回值
Function
- 关闭 loading 的函数
使用示例
javascript
// 基础用法
const closeLoading = showLoading()
// 关闭loading
closeLoading()
// 在指定元素上显示loading
const el = document.querySelector('.container')
showLoading({
target: el,
fullscreen: false,
text: '加载中...'
})
源码
源码
js
/**
* 显示/关闭加载中遮罩层
* @author chuxiao
* @param {string|Object} textOrOptions - 加载提示文本或配置选项
* @param {Object} [options={}] - 配置选项
* @param {string} [options.text='加载中...'] - 加载提示文本
* @param {boolean} [options.fullscreen=true] - 是否全屏显示
* @param {string} [options.background='rgba(0, 0, 0, 0.7)'] - 遮罩背景色
* @param {HTMLElement} [options.target] - 遮罩挂载的目标元素,在非全屏模式下生效
* @param {boolean} [options.lock=false] - 是否锁定屏幕滚动
* @returns {Function} 关闭loading的函数
*
* @example
* // 基础用法-显示全屏loading
* const closeLoading = showLoading();
* // 关闭loading
* closeLoading();
*
* // 显示带文本的loading
* showLoading('数据加载中...');
*
* // 在指定元素上显示loading
* const el = document.querySelector('.container');
* showLoading({
* target: el,
* fullscreen: false,
* text: '加载中...'
* });
*/
function showLoading(textOrOptions, options = {}) {
let text, finalOptions;
if(typeof textOrOptions === 'string') {
text = textOrOptions;
finalOptions = options;
} else if(textOrOptions) {
text = textOrOptions.text;
finalOptions = textOrOptions;
} else {
text = '加载中...';
finalOptions = options;
}
const {
fullscreen = true,
background = 'rgba(0, 0, 0, 0.7)',
target = document.body,
lock = false
} = finalOptions;
// 创建loading容器
const loadingContainer = document.createElement('div');
loadingContainer.className = 'el-loading-mask';
loadingContainer.style.cssText = `
position: ${fullscreen ? 'fixed' : 'absolute'};
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: ${background};
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
transition: opacity 0.3s;
z-index: 2000;
`;
// 创建loading图标
const spinner = document.createElement('div');
spinner.className = 'el-loading-spinner';
spinner.innerHTML = `
<svg class="circular" viewBox="25 25 50 50">
<circle class="path" cx="50" cy="50" r="20" fill="none"/>
</svg>
`;
// 添加loading文本
if(text) {
const textEl = document.createElement('p');
textEl.className = 'el-loading-text';
textEl.textContent = text;
textEl.style.cssText = `
margin: 3px 0 0;
color: #409eff;
font-size: 14px;
`;
spinner.appendChild(textEl);
}
loadingContainer.appendChild(spinner);
// 添加样式
const style = document.createElement('style');
style.textContent = `
.el-loading-spinner {
display: flex;
flex-direction: column;
align-items: center;
}
.circular {
width: 42px;
height: 42px;
animation: loading-rotate 2s linear infinite;
}
.path {
stroke-dasharray: 90,150;
stroke-dashoffset: 0;
stroke-width: 2;
stroke: #409eff;
stroke-linecap: round;
animation: loading-dash 1.5s ease-in-out infinite;
}
@keyframes loading-rotate {
100% {
transform: rotate(360deg);
}
}
@keyframes loading-dash {
0% {
stroke-dasharray: 1,200;
stroke-dashoffset: 0;
}
50% {
stroke-dasharray: 90,150;
stroke-dashoffset: -40px;
}
100% {
stroke-dasharray: 90,150;
stroke-dashoffset: -120px;
}
}
`;
document.head.appendChild(style);
// 锁定滚动
if(lock) {
document.body.style.overflow = 'hidden';
}
// 添加到目标元素
if(!fullscreen && target !== document.body) {
if(getComputedStyle(target).position === 'static') {
target.style.position = 'relative';
}
}
target.appendChild(loadingContainer);
// 关闭loading的函数
const close = () => {
loadingContainer.style.opacity = '0';
setTimeout(() => {
target.removeChild(loadingContainer);
document.head.removeChild(style);
if(lock) {
document.body.style.overflow = '';
}
}, 300);
};
return close;
}