fix: meta theme color flash issue

This commit is contained in:
radishzzz 2025-02-18 17:10:40 +00:00
parent 1040aff64c
commit b1777ed0ef
3 changed files with 60 additions and 52 deletions

View file

@ -26,7 +26,6 @@ function initScrollbar() {
}
}
document.addEventListener('theme-changed', initScrollbar)
document.addEventListener('astro:after-swap', initScrollbar)
initScrollbar()
</script>

View file

@ -19,6 +19,22 @@ const { light: { background: lightMode }, dark: { background: darkMode } } = the
</button>
<script define:vars={{ lightMode, darkMode }}>
// Update theme
function updateTheme() {
// Toggle website theme
document.documentElement.classList.toggle('dark')
// Get current theme
const isDark = document.documentElement.classList.contains('dark')
// Update meta theme color
const metaThemeColor = document.querySelector('meta[name="theme-color"]')
if (metaThemeColor) {
metaThemeColor.setAttribute('content', isDark ? darkMode : lightMode)
}
// Update theme configuration in local storage
localStorage.setItem('theme', isDark ? 'dark' : 'light')
document.dispatchEvent(new Event('theme-changed'))
}
// Bind click event to the button
function setupThemeToggle() {
// Locate theme toggle button
@ -43,22 +59,6 @@ function setupThemeToggle() {
})
}
// Update theme
function updateTheme() {
// Toggle website theme
document.documentElement.classList.toggle('dark')
// Get current theme
const isDark = document.documentElement.classList.contains('dark')
// Update meta theme color
const metaTheme = document.querySelector('meta[name="theme-color"]')
if (metaTheme) {
metaTheme.setAttribute('content', isDark ? darkMode : lightMode)
}
// Update theme configuration in local storage
localStorage.setItem('theme', isDark ? 'dark' : 'light')
document.dispatchEvent(new Event('theme-changed'))
}
// Initialize click event (on first load or page transition)
document.addEventListener('astro:after-swap', setupThemeToggle)
setupThemeToggle()

View file

@ -28,7 +28,7 @@ const { commentURL = '', imageHostURL = '', customGoogleAnalyticsURL = '', custo
<meta name="description" content={postDescription || description} />
<meta name="author" content={author} />
<meta name="generator" content={Astro.generator} />
<meta name="theme-color" content={lightMode} />
<meta name="theme-color" content="" />
<ClientRouter fallback="swap" />
<!-- Preload -->
@ -79,55 +79,64 @@ const { commentURL = '', imageHostURL = '', customGoogleAnalyticsURL = '', custo
is:inline
define:vars={{ defaultMode: themeConfig.color.mode, lightMode, darkMode }}
>
// Initialize theme
function initTheme() {
const theme = (() => {
// Check if current theme is dark mode
function isCurrentDark() {
const currentTheme = localStorage.getItem('theme')
// First priority: theme from localStorage
// Check local storage theme first
if (currentTheme)
return currentTheme
// Second priority: user configured default theme
return currentTheme === 'dark'
// Use configured default theme if available
if (defaultMode)
return defaultMode
// Last priority: follow system theme
return defaultMode === 'dark'
// Finally follow system color scheme preference
return window.matchMedia('(prefers-color-scheme: dark)').matches
? 'dark'
: 'light'
})()
// Update website theme
const isDark = theme === 'dark'
}
// Update site theme
function updateThemeColor(isDark) {
document.documentElement.classList.toggle('dark', isDark)
}
// Update meta theme color
function updateMetaThemeColor(isDark) {
const metaTheme = document.querySelector('meta[name="theme-color"]')
if (metaTheme) {
metaTheme.setAttribute('content', isDark ? darkMode : lightMode)
}
}
// Update theme
function updateTheme() {
// Read theme from localStorage
const isDark = localStorage.getItem('theme') === 'dark'
// Set theme directly instead of toggling
document.documentElement.classList.toggle('dark', isDark)
const metaTheme = document.querySelector('meta[name="theme-color"]')
if (metaTheme) {
metaTheme.setAttribute('content', isDark ? darkMode : lightMode)
}
// 1.Update meta theme color before page transition to prevent flashing
document.addEventListener('astro:before-swap', () => {
const isDark = isCurrentDark()
updateMetaThemeColor(isDark)
})
// 2.Update site theme after page transition
document.addEventListener('astro:after-swap', () => {
const isDark = isCurrentDark()
updateThemeColor(isDark)
})
// 3.Initialize theme on first load
const isDark = isCurrentDark()
updateThemeColor(isDark)
updateMetaThemeColor(isDark)
// Follow system theme changes automatically
function followSystemTheme() {
const isDark = isCurrentDark()
updateDocumentTheme(isDark)
updateMetaThemeColor(isDark)
document.dispatchEvent(new Event('theme-changed'))
}
// Listen to system theme changes in real-time
// 4.Listen to system theme changes in real-time
window
.matchMedia('(prefers-color-scheme: dark)')
.addEventListener('change', ({ matches: isDark }) => {
localStorage.setItem('theme', isDark ? 'dark' : 'light')
updateTheme()
followSystemTheme()
})
// Initialize theme (on first load or page transition)
document.addEventListener('astro:after-swap', initTheme)
initTheme()
</script>
<!-- Google Analytics -->