optimized js
This commit is contained in:
@@ -1,17 +1,17 @@
|
|||||||
class ThemeManager {
|
class ThemeManager {
|
||||||
constructor() {
|
constructor() {
|
||||||
// Cache DOM elements once
|
|
||||||
this.toggle = document.getElementById('theme-toggle');
|
this.toggle = document.getElementById('theme-toggle');
|
||||||
this.icon = document.getElementById('theme-icon');
|
if (!this.toggle) return;
|
||||||
|
|
||||||
// Get data attributes once
|
this.icon = document.getElementById('theme-icon');
|
||||||
const { iconBase, iconDark, iconLight, soundSrc } = this.toggle.dataset;
|
const { iconBase, iconDark, iconLight, soundSrc } = this.toggle.dataset;
|
||||||
this.iconBase = iconBase;
|
this.iconBase = iconBase;
|
||||||
this.iconDark = iconDark;
|
this.iconDark = iconDark;
|
||||||
this.iconLight = iconLight;
|
this.iconLight = iconLight;
|
||||||
|
|
||||||
// Create audio element only when needed
|
// Create audio element lazily only when needed
|
||||||
this.sound = new Audio(soundSrc);
|
this.sound = null;
|
||||||
|
this.soundSrc = soundSrc;
|
||||||
|
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
@@ -34,31 +34,31 @@ class ThemeManager {
|
|||||||
const isDark = document.documentElement.getAttribute('data-theme') === 'dark';
|
const isDark = document.documentElement.getAttribute('data-theme') === 'dark';
|
||||||
const newTheme = isDark ? 'light' : 'dark';
|
const newTheme = isDark ? 'light' : 'dark';
|
||||||
|
|
||||||
document.body.classList.add('theme-transition');
|
|
||||||
document.documentElement.setAttribute('data-theme', newTheme);
|
document.documentElement.setAttribute('data-theme', newTheme);
|
||||||
|
|
||||||
// Use the inverse to update the icon to match the new theme
|
|
||||||
this.updateIcon(!isDark);
|
this.updateIcon(!isDark);
|
||||||
|
|
||||||
localStorage.setItem('theme', newTheme);
|
localStorage.setItem('theme', newTheme);
|
||||||
|
|
||||||
// Use requestAnimationFrame for better performance on transition
|
// Lazy load sound only when needed
|
||||||
requestAnimationFrame(() => {
|
if (!this.sound && this.soundSrc) {
|
||||||
setTimeout(() => {
|
this.sound = new Audio(this.soundSrc);
|
||||||
document.body.classList.remove('theme-transition');
|
|
||||||
}, 300);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.sound.play().catch(() => {});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.sound) {
|
||||||
|
this.sound.play().catch(() => {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Extracted common functionality
|
|
||||||
updateIcon(isDark) {
|
updateIcon(isDark) {
|
||||||
|
if (this.icon) {
|
||||||
this.icon.setAttribute('href',
|
this.icon.setAttribute('href',
|
||||||
`${this.iconBase}${isDark ? this.iconDark : this.iconLight}`);
|
`${this.iconBase}${isDark ? this.iconDark : this.iconLight}`);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use modern syntax
|
// Initialize when content is loaded
|
||||||
document.addEventListener('DOMContentLoaded', () => new ThemeManager());
|
if (document.readyState === 'loading') {
|
||||||
|
document.addEventListener('DOMContentLoaded', () => new ThemeManager());
|
||||||
|
} else {
|
||||||
|
new ThemeManager();
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<div {% if class %}class="{{class}}"{% endif %}>
|
<div {% if class %}class="{{class}}"{% endif %}>
|
||||||
<iframe
|
<iframe
|
||||||
src="https://www.youtube-nocookie.com/embed/{{id}}{% if autoplay %}?autoplay=1{% endif %}"
|
src="https://www.youtube-nocookie.com/embed/{{id}}{% if autoplay %}?autoplay=1{% endif %}"
|
||||||
|
loading="lazy"
|
||||||
frameborder="0"
|
frameborder="0"
|
||||||
allow="accelerometer; encrypted-media; gyroscope; picture-in-picture"
|
allow="accelerometer; encrypted-media; gyroscope; picture-in-picture"
|
||||||
webkitallowfullscreen
|
webkitallowfullscreen
|
||||||
|
|||||||
Reference in New Issue
Block a user