换肤@Skin

获取关键数据修改目标元素样式达到换肤的效果;注意权值

关键数据可以来自:

元素属性,如:样式的类、内联样式、样式属性值或其它属性,如自定义属性
变量,如全局变量或局部变量

同样的,修改目标元素的样式,可以通过修改:

样式的类、内联样式、样式属性值或其它属性
变量,如全局变量或局部变量
内联样式 style

说明:本节案例,重在关键数据的获取

获取某个元素的内联样式,修改另外一个元素的内联样式

<div id="red" style="background-color: #ff0f5b; --color: #ff0f5b" data-color='#ff0f5b'>red</div>

获取元素

let body = document.body
let colorObj = document.querySelector('#color')
方案1:直接获取对象样式 backgroundColor
colorObj.addEventListener('click', () => {
  let color= colorObj.style.backgroundColor
  body.style.backgroundColor = color
})      
方案2:获取事件对象 target
colorObj.addEventListener('click', (e) => {
  let color = e.target.style.getPropertyValue('background-color')
  body.style.backgroundColor = color
})
方案3:获取内联变量 --color
colorObj.addEventListener('click', (e) => {
  let color = e.target.style.getPropertyValue('--color')
  body.style.backgroundColor = color
})
方案4:获取自定义属性 data-color
colorObj.addEventListener('click', (e) => {
  let color = e.target.dataset.color
  body.style.backgroundColor = color
})
类 class

指定不同的类而应用不同的样式

方案1:切换类 - 两套变量;推荐
:root {
  --txt-color: #303133;
  --bg-color: #f1f1f1;
  --shadow-color: rgba(0, 0, 0, 0.1);
}

body.dark {
  --txt-color: #f1f1f1;
  --bg-color: #131313;
  --shadow-color: rgba(255, 255, 255, 0.1);
}      

单击时,切换主题类

btnTheme.addEventListener('click', () => {
  body.classList.toggle('dark')
})      
方案2:为根元素 body 设置白天和黑夜两套全局变量,使用属性选择器加以区分
:root {
  --txt-color: #303133;
  --bg-color: #ffffff;
}

[data-theme="dark"] {
  --txt-color: #e5eaf3;
  --bg-color: #131313;
}

默认是白天,单击/交互时,<html>添加主题属性,修改为暗夜模式

document.documentElement.setAttribute('data-theme', 'dark');

或:新增加一个变量,保存当前模式;根据当前模式切换主题;可以使用 本地存储 - localStorage 或远端保存用户选择;还可以使用特定设计,如 路径剪切 clip-path 实现过渡效果

document.documentElement.setAttribute('data-theme', isDarkMode.value ? 'dark' : 'light');
全局变量

比较优雅且现代 - 只需要提供一套变量定义;修改少量关键变量即可实现

:root {
  --txt-color: #303133;
  --bg-color: #f1f1f1;
  --shadow-color: rgba(0, 0, 0, 0.1);
}      
单击时,修改变量的值;可以加入更多设计
btnTheme.addEventListener('click', () => {
  document.documentElement.style.setProperty('--txt-color', '#f1f1f1')
  document.documentElement.style.setProperty('--bg-color', '#303133')
})      
媒体查询 @media
使用媒体查询检测用户的系统偏好设置,由用户操作系统触发;建议配合js,由用户触发
Win + I → 个性化 → 颜色 → 选择模式 → 深色
不是:系统 → 屏幕 → 夜间模式
使用 console.log() 在 JavaScript 中输出 window.matchMedia('(prefers-color-scheme: dark)').matches 的结果,确认是否返回预期的布尔值
:root {
  --txt-color: #303133;
  --bg-color: #f1f1f1;
  --shadow-color: rgba(0, 0, 0, 0.1);
}

@media (prefers-color-scheme: dark) {
  :root {
    --txt-color: #f1f1f1;
    --bg-color: #131313;
    --shadow-color: rgba(255, 255, 255, 0.1);
  }
}
主题 Theme
操作对象
操作 <html> 标签

更加全局,影响整个文档

可以用于应用全局样式,如字体大小、颜色主题等

在响应式设计中,有时会用 <html> 的类来控制全局的缩放或布局

操作 <body> 标签

影响 <body> 内的所有内容,不包括 <head> 部分

适用于页面内容的样式更改,如背景色、字体等

如果样式仅应用于页面可见区域,使用 <body> 可能更合适

实现
通常还借助 本地存储 - LocalStorage 保存用户选择的主题
方案1:通过添加或移除类
html {
  --txt-color: #303133;
  --bg-color: #f1f1f1;
  --shadow-color: rgba(0, 0, 0, 0.1);
}

html.dark-theme {
  --txt-color: #f1f1f1;
  --bg-color: #131313;
  --shadow-color: rgba(255, 255, 255, 0.1);
}      
  function toggleTheme() {
    /* html*/
    document.documentElement.classList.toggle('dark-theme');
    /* 或 body*/
    document.body.classList.toggle('dark-theme');
  }
方案2:通过添加或移除属性 - :root是<html>的一个属性
/* light theme */
:root {
  --txt-color: #303133;
  --bg-color: #f1f1f1;
  --shadow-color: rgba(0, 0, 0, 0.1);
}

/* dark theme */
:root[data-theme="dark"] {
  --txt-color: #f1f1f1;
  --bg-color: #131313;
  --shadow-color: rgba(255, 255, 255, 0.1);
}      
document.documentElement.setAttribute('data-theme', isDarkMode.value ? 'dark' : 'light'); 
方案3:直接修改变量的值;详情请查看 CSS变量
其它方案:。。。
[] 主题切换