iT邦幫忙

0

從零打造輔大課表神器:Chrome Extension 開發實戰 30 天 - Day 24

  • 分享至 

  • xImage
  •  

Day 24:課表HTML模板與基礎樣式

🎯 系列目標:用 30 天時間,從零開始打造一個專屬輔大學生的課表生成 Chrome 擴充功能

💻 作者:輔大智慧資安 412580084

📅 Day 24:課表HTML模板與基礎樣式

🔗 課程系列回顧

昨天 Day 23 我們建立了完整的 Chrome Storage 儲存機制,今天我們要開始設計課表的視覺介面,建立 HTML 模板和基礎樣式系統。

📋 學習目標

今天我們要完成:

  1. 🏗️ 建立課表HTML模板結構
  2. 🎨 設計基礎CSS樣式系統
  3. 📱 實作響應式設計基礎
  4. 🧪 測試模板載入功能

🏗️ 課表HTML模板結構

1.1 基礎HTML架構設計

這裡我們選擇使用 table 元素來更好管理 DOM :

<!DOCTYPE html>
<html lang="zh-TW">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>輔大課表 - 個人化課程表</title>
    <link rel="stylesheet" href="schedule-styles.css">
</head>
<body>
    <div class="schedule-container">
        <!-- 控制面板 -->
        <div class="controls-panel">
            <button id="refreshDataBtn" class="control-btn">
                🔄 重新載入
            </button>
            
            <select id="themeSelector" class="theme-selector">
                <option value="default">🌟 預設主題</option>
                <option value="forest">🌲 森林主題</option>
                <option value="ocean">🌊 海洋主題</option>
            </select>
            
            <button id="exportBtn" class="control-btn">
                📥 匯出課表
            </button>
        </div>

        <!-- 學生資訊區域 -->
        <section class="student-info-section">
            <div class="student-card">
                <h2 class="student-title">學生資訊</h2>
                <div class="student-details" id="studentDetails">
                    <div class="info-item">
                        <span class="info-label">學期:</span>
                        <span class="info-value" id="semesterInfo">載入中...</span>
                    </div>
                    <div class="info-item">
                        <span class="info-label">系級:</span>
                        <span class="info-value" id="departmentInfo">載入中...</span>
                    </div>
                    <div class="info-item">
                        <span class="info-label">學號:</span>
                        <span class="info-value" id="studentIdInfo">載入中...</span>
                    </div>
                </div>
            </div>
        </section>

        <!-- 課表主體 -->
        <section class="schedule-section">
            <h2 class="schedule-title">我的課表</h2>
            <div class="schedule-wrapper">
                <table class="schedule-table" id="scheduleTable">
                    <thead>
                        <tr class="schedule-header">
                            <th class="time-header">時間</th>
                            <th class="day-header">週一</th>
                            <th class="day-header">週二</th>
                            <th class="day-header">週三</th>
                            <th class="day-header">週四</th>
                            <th class="day-header">週五</th>
                        </tr>
                    </thead>
                    <tbody id="scheduleBody">
                        <!-- 課表內容將由 JavaScript 動態生成 -->
                    </tbody>
                </table>
            </div>
        </section>
    </div>

    <script src="schedule-renderer.js"></script>
</body>
</html>

🎨 基礎CSS樣式系統

2.1 CSS變數與主題基礎

這裡使用:root 以為了之後的變換主題樣式的設計

/* CSS 變數定義與主題系統 */
:root {
  /* 主要色彩 */
  --primary-color: #2563eb;
  --primary-hover: #1d4ed8;
  --primary-light: #dbeafe;
  
  /* 背景色彩 */
  --background-main: #ffffff;
  --background-secondary: #f8fafc;
  --background-card: #ffffff;
  
  /* 文字色彩 */
  --text-primary: #1e293b;
  --text-secondary: #64748b;
  
  /* 間距系統 */
  --spacing-sm: 0.5rem;
  --spacing-md: 1rem;
  --spacing-lg: 1.5rem;
  --spacing-xl: 2rem;
  
  /* 圓角設定 */
  --radius-md: 0.5rem;
  --radius-lg: 0.75rem;
  
  /* 陰影效果 */
  --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
  --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1);
}

/* 森林主題 */
[data-theme="forest"] {
  --primary-color: #16a34a;
  --primary-hover: #15803d;
  --background-main: #f0fdf4;
}

/* 海洋主題 */
[data-theme="ocean"] {
  --primary-color: #0891b2;
  --primary-hover: #0e7490;
  --background-main: #f0f9ff;
}

2.2 元件樣式設計

這裡可以根據自己的想法設計:

/* 基礎重置與全域樣式 */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: 'Microsoft JhengHei', sans-serif;
  background-color: var(--background-main);
  color: var(--text-primary);
  line-height: 1.6;
}

/* 主容器 */
.schedule-container {
  max-width: 1200px;
  margin: 0 auto;
  padding: var(--spacing-lg);
  background-color: var(--background-main);
}

/* 控制面板樣式 */
.controls-panel {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--spacing-md);
  margin-bottom: var(--spacing-xl);
  padding: var(--spacing-md);
  background-color: var(--background-card);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}

.control-btn {
  padding: var(--spacing-sm) var(--spacing-md);
  background-color: var(--primary-color);
  color: white;
  border: none;
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: all 0.2s ease;
}

.control-btn:hover {
  background-color: var(--primary-hover);
  transform: translateY(-1px);
}

/* 學生資訊卡片 */
.student-card {
  background-color: var(--background-card);
  border-radius: var(--radius-lg);
  padding: var(--spacing-lg);
  box-shadow: var(--shadow-md);
  margin-bottom: var(--spacing-xl);
}

.student-details {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--spacing-md);
}

.info-item {
  display: flex;
  gap: var(--spacing-sm);
}

.info-label {
  font-weight: 500;
  color: var(--text-secondary);
}

.info-value {
  font-weight: 600;
  color: var(--text-primary);
}

/* 課表樣式 */
.schedule-table {
  width: 100%;
  border-collapse: collapse;
  background-color: var(--background-card);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-md);
}

.schedule-table th,
.schedule-table td {
  padding: var(--spacing-md);
  text-align: center;
  border: 1px solid #e2e8f0;
}

.schedule-header {
  background-color: var(--primary-color);
  color: white;
}

.schedule-table tbody tr:nth-child(even) {
  background-color: var(--background-secondary);
}

.schedule-table tbody tr:hover {
  background-color: var(--primary-light);
}

/* 響應式設計 */
@media (max-width: 768px) {
  .controls-panel {
    flex-direction: column;
    gap: var(--spacing-sm);
  }
  
  .student-details {
    grid-template-columns: 1fr;
  }
  
  .schedule-table {
    font-size: 0.875rem;
  }
}

🧪 模板測試功能

3.1 基礎模板載入器

建立簡單的 JavaScript 測試器來驗證模板:

// 簡單的模板測試器
class ScheduleTemplateTest {
  constructor() {
    this.log('📋 課表模板測試器初始化');
  }

  // 測試模板載入
  testTemplateLoad() {
    console.log('🧪 開始測試模板載入');
    
    // 檢查必要元素
    const requiredElements = [
      'refreshDataBtn',
      'themeSelector', 
      'studentDetails',
      'scheduleTable'
    ];
    
    requiredElements.forEach(id => {
      const element = document.getElementById(id);
      if (element) {
        console.log(`✅ 元素 ${id} 載入成功`);
      } else {
        console.error(`❌ 元素 ${id} 載入失敗`);
      }
    });
  }

  // 測試主題切換
  testThemeSwitch() {
    const themeSelector = document.getElementById('themeSelector');
    if (themeSelector) {
      themeSelector.addEventListener('change', (e) => {
        document.documentElement.setAttribute('data-theme', e.target.value);
        console.log(`🎨 主題切換至: ${e.target.value}`);
      });
    }
  }

  // 測試時間段配置(與 schedule.js 一致)
  testPeriodConfiguration() {
    const periods = ['1', '2', '3', '4', 'DN', '5', '6', '7', '8', 'E0'];
    const periodTimeMap = {
      '1': '1<br>08:10-09:00',
      '2': '2<br>09:10-10:00',
      '3': '3<br>10:10-11:00',
      '4': '4<br>11:10-12:00',
      'DN': 'DN<br>12:10-13:00 <br>or <br> 12:40-13:30',
      '5': '5<br>13:40-14:30',
      '6': '6<br>14:40-15:30',
      '7': '7<br>15:40-16:30',
      '8': '8<br>16:40-17:30',
      'E0': 'E0<br>17:40-18:30'
    };
    
    console.log('🕒 測試時間段配置:');
    periods.forEach(period => {
      console.log(`${period}: ${periodTimeMap[period].replace(/<br>/g, ' ')}`);
    });
  }

  log(message) {
    console.log(`[TemplateTest] ${message}`);
  }
}

// 執行測試
document.addEventListener('DOMContentLoaded', () => {
  const tester = new ScheduleTemplateTest();
  tester.testTemplateLoad();
  tester.testThemeSwitch();
  tester.testPeriodConfiguration();
});

之後我們在輔大學生入口網中點擊我的課表會看到schedule.html顯示:
2


🎯 明日預告

今天我們建立了完整的HTML模板和樣式基礎,明天我們要實現課表渲染引擎與資料綁定


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言