Skip to content

加载器 Loader

加载器是显示内容正在加载的反馈组件。

基础用法

基础加载器

html
<div class="glass-loader spinner-headless medium">
  <div class="spinner-ring"></div>
</div>

预览效果:

加载器尺寸

html
<!-- 小尺寸 -->
<div class="glass-loader spinner-headless small">
  <div class="spinner-ring"></div>
</div>

<!-- 中等尺寸 -->
<div class="glass-loader spinner-headless medium">
  <div class="spinner-ring"></div>
</div>

<!-- 大尺寸 -->
<div class="glass-loader spinner-headless large">
  <div class="spinner-ring"></div>
</div>

预览效果:

带文字的加载器

html
<div class="glass-loader">
  <div class="loader-spinner"></div>
  <div class="loader-text">加载中...</div>
</div>

内联加载器

html
<button class="glass-button">
  <div class="glass-loader inline">
    <div class="loader-spinner"></div>
  </div>
  处理中
</button>

加载器类型

圆形加载器

html
<div class="glass-loader">
  <div class="loader-spinner circle"></div>
</div>

点状加载器

html
<div class="glass-loader">
  <div class="loader-dots">
    <span class="dot"></span>
    <span class="dot"></span>
    <span class="dot"></span>
  </div>
</div>

进度条加载器

html
<div class="glass-loader">
  <div class="loader-progress">
    <div class="progress-bar"></div>
  </div>
  <div class="loader-text">加载中 60%</div>
</div>

加载器尺寸

html
<!-- 小尺寸 -->
<div class="glass-loader small">
  <div class="loader-spinner"></div>
</div>

<!-- 默认尺寸 -->
<div class="glass-loader">
  <div class="loader-spinner"></div>
</div>

<!-- 大尺寸 -->
<div class="glass-loader large">
  <div class="loader-spinner"></div>
</div>

CSS 类名

基础类名

  • .glass-loader - 加载器容器
  • .loader-spinner - 旋转加载器
  • .loader-dots - 点状加载器
  • .loader-progress - 进度条加载器
  • .loader-text - 加载文字
  • .dot - 加载点
  • .progress-bar - 进度条

修饰类名

类型修饰符

  • .circle - 圆形样式
  • .inline - 内联样式

尺寸修饰符

  • .small - 小尺寸
  • .large - 大尺寸

JavaScript 增强

显示和隐藏加载器

javascript
class LoaderManager {
  constructor() {
    this.activeLoaders = new Set();
  }
  
  show(target, options = {}) {
    const {
      text = '加载中...',
      type = 'spinner',
      overlay = true
    } = options;
    
    const loader = this.createLoader(text, type, overlay);
    
    if (typeof target === 'string') {
      target = document.querySelector(target);
    }
    
    target.appendChild(loader);
    this.activeLoaders.add(loader);
    
    return loader;
  }
  
  hide(loader) {
    if (loader && loader.parentNode) {
      loader.parentNode.removeChild(loader);
      this.activeLoaders.delete(loader);
    }
  }
  
  hideAll() {
    this.activeLoaders.forEach(loader => {
      this.hide(loader);
    });
  }
  
  createLoader(text, type, overlay) {
    const loader = document.createElement('div');
    loader.className = `glass-loader${overlay ? ' overlay' : ''}`;
    
    let content = '';
    
    switch (type) {
      case 'dots':
        content = `
          <div class="loader-dots">
            <span class="dot"></span>
            <span class="dot"></span>
            <span class="dot"></span>
          </div>
        `;
        break;
      case 'progress':
        content = `
          <div class="loader-progress">
            <div class="progress-bar"></div>
          </div>
        `;
        break;
      default:
        content = '<div class="loader-spinner"></div>';
    }
    
    if (text) {
      content += `<div class="loader-text">${text}</div>`;
    }
    
    loader.innerHTML = content;
    return loader;
  }
}

// 使用示例
const loaderManager = new LoaderManager();

// 显示加载器
const loader = loaderManager.show('#content', {
  text: '数据加载中...',
  type: 'spinner'
});

// 3秒后隐藏
setTimeout(() => {
  loaderManager.hide(loader);
}, 3000);

按钮加载状态

javascript
function setButtonLoading(button, loading = true) {
  if (loading) {
    button.disabled = true;
    button.dataset.originalText = button.textContent;
    
    const loader = document.createElement('div');
    loader.className = 'glass-loader inline small';
    loader.innerHTML = '<div class="loader-spinner"></div>';
    
    button.insertBefore(loader, button.firstChild);
    button.classList.add('loading');
  } else {
    button.disabled = false;
    const loader = button.querySelector('.glass-loader');
    if (loader) {
      loader.remove();
    }
    button.classList.remove('loading');
    
    if (button.dataset.originalText) {
      button.textContent = button.dataset.originalText;
      delete button.dataset.originalText;
    }
  }
}

// 使用示例
const submitButton = document.querySelector('#submit-btn');

submitButton.addEventListener('click', async () => {
  setButtonLoading(submitButton, true);
  
  try {
    await submitForm();
  } finally {
    setButtonLoading(submitButton, false);
  }
});

应用场景

页面加载

html
<div id="page-loader" class="glass-loader overlay">
  <div class="loader-spinner large"></div>
  <div class="loader-text">页面加载中...</div>
</div>

<style>
.glass-loader.overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(255, 255, 255, 0.8);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  z-index: 9999;
}
</style>

数据加载

html
<div class="data-container">
  <div class="glass-loader" id="data-loader">
    <div class="loader-spinner"></div>
    <div class="loader-text">正在获取数据...</div>
  </div>
  
  <div class="data-content" style="display: none;">
    <!-- 数据内容 -->
  </div>
</div>

表单提交

html
<form class="glass-form">
  <div class="form-group">
    <input type="text" class="glass-input" placeholder="用户名">
  </div>
  
  <div class="form-group">
    <input type="password" class="glass-input" placeholder="密码">
  </div>
  
  <button type="submit" class="glass-button primary large" id="login-btn">
    登录
  </button>
</form>

<script>
document.querySelector('#login-btn').addEventListener('click', (e) => {
  e.preventDefault();
  
  // 显示加载状态
  setButtonLoading(e.target, true);
  e.target.textContent = '登录中...';
  
  // 模拟登录请求
  setTimeout(() => {
    setButtonLoading(e.target, false);
    e.target.textContent = '登录';
  }, 2000);
});
</script>

图片懒加载

html
<div class="image-container">
  <div class="glass-loader" id="image-loader">
    <div class="loader-spinner"></div>
    <div class="loader-text">图片加载中...</div>
  </div>
  
  <img src="large-image.jpg" onload="hideImageLoader()" style="display: none;">
</div>

<script>
function hideImageLoader() {
  document.querySelector('#image-loader').style.display = 'none';
  document.querySelector('img').style.display = 'block';
}
</script>

Released under the MIT License.