Omni主題切換API:開發者集成主題切換功能的接口
你是否在開發擴展時遇到過主題適配難題?Omni的主題切換API讓開發者能夠輕鬆集成暗色/亮色主題切換功能,無需手動管理複雜的樣式變量。本文將詳解如何使用Omni的主題系統,實現跟隨系統設置或手動控制的主題切換功能。
主題系統基礎架構
Omni通過CSS變量和媒體查詢實現主題切換,核心定義在src/content.css文件中。系統採用雙主題模式設計,通過CSS變量隔離不同主題的樣式屬性。
主題變量定義
Omni使用CSS變量定義主題樣式,主要包含背景色、邊框色、文本色等基礎屬性:
/* 暗色主題變量 - [src/content.css](https://link.gitcode.com/i/708b5a6dea380e95944d7603ca38865e) L32-L45 */
@media (prefers-color-scheme: dark) {
.omni-extension {
--background: #1e2128;
--border: #35373e;
--text: #f1f1f1;
--text-2: #c5c6ca;
--text-3: #a5a5ae;
--select: #17191e;
--accent: #6068d2;
--accent-hover: #484fac;
--shortcut: #383e4a;
--placeholder: #63687b;
--background-2: #292d36;
}
}
/* 亮色主題變量 - [src/content.css](https://link.gitcode.com/i/708b5a6dea380e95944d7603ca38865e) L47-L60 */
@media (prefers-color-scheme: light) {
.omni-extension {
--background: #fafcff;
--border: #f2f3fb;
--text: #2b2d41;
--text-2: #2b2d41;
--text-3: #929db2;
--select: #eff3f9;
--accent: #6068d2;
--accent-hover: #484fac;
--shortcut: #dadeea;
--placeholder: #bac2d1;
--background-2: #292d36;
}
}
主題切換原理
Omni主題系統基於CSS媒體查詢prefers-color-scheme實現自動切換,當系統主題變化時,瀏覽器會自動應用對應主題的CSS變量。開發者可以通過JavaScript接口覆蓋系統設置,實現手動主題控制。
API接口使用指南
檢測當前主題模式
通過window.matchMediaAPI可以檢測用户系統的主題偏好:
// 檢測系統主題偏好
const isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches;
console.log('當前系統主題:', isDarkMode ? '暗色' : '亮色');
手動切換主題
要實現手動主題切換,需要動態修改根元素的類名,覆蓋CSS媒體查詢的默認行為:
// 手動切換到暗色主題
document.documentElement.classList.add('dark-mode');
document.documentElement.classList.remove('light-mode');
// 手動切換到亮色主題
document.documentElement.classList.add('light-mode');
document.documentElement.classList.remove('dark-mode');
監聽主題變化
通過監聽媒體查詢的變化事件,可以實時響應系統主題切換:
// 監聽主題變化
const themeQuery = window.matchMedia('(prefers-color-scheme: dark)');
themeQuery.addEventListener('change', (e) => {
const newTheme = e.matches ? 'dark' : 'light';
console.log('系統主題已切換為:', newTheme);
// 在這裏更新UI或存儲用户偏好
});
集成示例:主題切換按鈕
以下是一個完整的主題切換按鈕實現示例,包含UI元素和交互邏輯:
<!-- 主題切換按鈕 -->
<button id="theme-toggle" class="omni-theme-toggle">
<svg class="theme-icon" width="24" height="24">
<!-- 太陽/月亮圖標 -->
</svg>
</button>
<style>
/* 主題切換按鈕樣式 */
.omni-theme-toggle {
background: var(--background);
border: 1px solid var(--border);
color: var(--text);
border-radius: 4px;
padding: 8px;
cursor: pointer;
}
.omni-theme-toggle:hover {
background: var(--background-2);
}
</style>
<script>
// 主題切換邏輯
const themeToggle = document.getElementById('theme-toggle');
let isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
// 初始化按鈕狀態
updateThemeIcon();
// 切換主題
themeToggle.addEventListener('click', () => {
isDark = !isDark;
document.documentElement.classList.toggle('dark-mode', isDark);
document.documentElement.classList.toggle('light-mode', !isDark);
updateThemeIcon();
// 可選:保存用户偏好到localStorage
localStorage.setItem('omni-theme', isDark ? 'dark' : 'light');
});
// 更新圖標
function updateThemeIcon() {
const icon = themeToggle.querySelector('.theme-icon');
icon.innerHTML = isDark ?
'<path d="M20.742 13.045a8.088 8.088 0 01-2.077.271c-2.135 0-4.14-.83-5.667-2.36a8.174 8.174 0 01-2.36-5.667c0-2.135.83-4.14 2.36-5.667A8.101 8.101 0 0113.045 2.077C15.818 2 18 4.182 18 7c0 2.818-2.182 5-5 5a8.287 8.287 0 01-.271 2.077 8.456 8.456 0 01.271 2.077 8.287 8.287 0 012.077.271 8.088 8.088 0 012.077-.271c2.818 0 5 2.182 5 5a8.18 8.18 0 01-.271 2.077z"/>' :
'<path d="M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10zm0-18c4.411 0 8 3.589 8 8s-3.589 8-8 8-8-3.589-8-8 3.589-8 8-8z"/>';
}
</script>
高級應用:持久化主題設置
為了提供更好的用户體驗,建議將用户的主題偏好保存到本地存儲,並在擴展啓動時恢復:
// 初始化主題
function initTheme() {
const savedTheme = localStorage.getItem('omni-theme');
const systemDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
// 優先級:保存的主題 > 系統主題
const isDark = savedTheme ? savedTheme === 'dark' : systemDark;
document.documentElement.classList.toggle('dark-mode', isDark);
document.documentElement.classList.toggle('light-mode', !isDark);
}
// 在擴展加載時調用
initTheme();
瀏覽器兼容性處理
Omni主題系統在Firefox和Chrome擴展中略有差異,主要體現在背景腳本的API調用上:
- Chrome版本:src/background.js
- Firefox版本:firefox/background.js
開發者在實現跨瀏覽器擴展時,需要注意使用不同瀏覽器的API前綴(chrome. vs browser.)。
總結與最佳實踐
Omni主題切換API提供了靈活的主題控制能力,通過CSS變量和媒體查詢的結合,實現了簡潔高效的主題管理方案。建議開發者:
- 始終使用CSS變量而非硬編碼顏色值
- 同時支持系統主題和手動切換
- 持久化保存用户主題偏好
- 在UI中提供明確的主題狀態指示
通過遵循這些實踐,你可以為用户提供一致且個性化的主題體驗,提升擴展的專業度和易用性。完整的主題實現代碼可參考src/content.css和firefox/content.css文件。