JS媒体查询之matchMedia API 实现跟随系统主题色切换效果

news2024/12/31 2:14:03

📊写在前面

在网页设计中,跟随系统主题切换可以通过CSS和JavaScript实现。可以通过定义两套CSS变量,根据系统主题的颜色来切换变量的生效,从而实现不同主题下的页面样式变化。
例如,可以使用媒体查询API来获取系统主题的颜色,并根据匹配结果来适配页面的自定义属性。同时,可以注册媒体查询的change事件,当系统主题变化时重新调用函数,实现跟随系统的效果。

🖼️API简介

Window 的 matchMedia() 方法返回一个新的 MediaQueryList 对象,表示指定的媒体查询字符串解析后的结果。返回的 MediaQueryList 可被用于判定 Document 是否匹配媒体查询,或者监控一个 document 来判定它匹配了或者停止匹配了此媒体查询。

🚀实际效果

在这里插入图片描述

📚实例代码(HTML版)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>JS媒体查询之matchMedia API 实现跟随系统主题色切换效果</title>
    <style>
        :root {
            --text-color: #333;
            --bg-color: #fff;
        }

        html[data-theme="dark"] {
            --text-color: #fff;
            --bg-color: #333;
        }

        html[data-theme="ligth"] {
            --text-color: #333;
            --bg-color: #fff;
        }

        html[data-theme="red"] {
            --text-color: #fff;
            --bg-color: #ff0064;
        }

        html[data-theme="green"] {
            --text-color: #fff;
            --bg-color: #67c23a;
        }

        html[data-theme="blue"] {
            --text-color: #fff;
            --bg-color: #0091db;
        }

        body {
            background-color: var(--bg-color);
            color: var(--text-color);
        }

        h1 {
            color: var(--text-color);
            text-align: center;
        }

        select {
            display: block;
            margin: 20px auto;
            font-size: 32px;
        }
    </style>
</head>

<body>
    <h1>JS媒体查询之matchMedia API 实现跟随系统主题色切换效果</h1>
    <hr>

    <select name="theme" id="theme">
        <option value="ligth">亮色</option>
        <option value="dark">暗色</option>
        <option value="os">系统跟随</option>
        <option value="red">红色</option>
        <option value="green">绿色</option>
        <option value="blue">蓝色</option>
    </select>

    <script>
        const theme = document.getElementById('theme');
        
        // 获取系统主题
        const metch = window.matchMedia('(prefers-color-scheme: dark)');

        // 设置主题
        const setTheme = (theme = '') => {
            document.documentElement.setAttribute('data-theme', theme ? theme : metch.matches ? 'dark' : 'ligth');
        };

        // 监听主题切换
        theme.addEventListener('change', (e) => {
            if ('os' === e.target.value) {
                setTheme();
                // 监听系统主题切换
                metch.addEventListener('change', setTheme);
            } else {
                setTheme(e.target.value);
                metch.removeEventListener('change', setTheme);
            }
        });
    </script>
</body>

</html>

📚实例代码(Vue3.js + TS版)

hook.ts

import { ref, watchEffect } from 'vue';

// 定义主题类型
type Theme = 'light' | 'dark' | 'os';

// 存储主题的key
const STORE_KEY = '__hteme__';

// 获取存储主题
const theme = ref<Theme>(localStorage.getItem(STORE_KEY) as Theme || 'light');

// 获取系统主题
const media = globalThis.matchMedia('(prefers-color-scheme: dark)');

// 监听系统主题变化
const listener = () => {
    document.documentElement.dataset.theme = media.matches ? 'dark' : 'light';
}

// 监听theme变量值变化
watchEffect(() => {
    // 更新存储
    localStorage.setItem(STORE_KEY, theme.value);

    if (theme.value === 'os') {
        // 设置系统主题
        listener();
        
        // 监听系统主题变化
        media.addEventListener('change', listener);

    } else {
        // 移除监听
        media.removeEventListener('change', listener);
        document.documentElement.dataset.theme = theme.value;
    }
});

export function useTheme() {
    return {
        theme
    }
};

demo.vue

<script setup lang="ts">
	import { useTheme } from '@/hooks/useTheme';
	const { theme } = useTheme()
</script>

<template>
	<h1>JS媒体查询之matchMedia API 实现跟随系统主题色切换效果</h1>
    <hr>
	<select v-model="theme">
		<option value="ligth">亮色</option>
        <option value="dark">暗色</option>
        <option value="os">系统跟随</option>
        <option value="red">红色</option>
        <option value="green">绿色</option>
        <option value="blue">蓝色</option>
	 </select>
</template>

<style>
    :root {
        --text-color: #333;
        --bg-color: #fff;
    }

    html[data-theme="dark"] {
        --text-color: #fff;
        --bg-color: #333;
    }

    html[data-theme="ligth"] {
        --text-color: #333;
        --bg-color: #fff;
    }

    html[data-theme="red"] {
        --text-color: #fff;
        --bg-color: #ff0064;
    }

    html[data-theme="green"] {
        --text-color: #fff;
        --bg-color: #67c23a;
    }

    html[data-theme="blue"] {
        --text-color: #fff;
        --bg-color: #0091db;
    }

    body {
        background-color: var(--bg-color);
        color: var(--text-color);
    }

    h1 {
        color: var(--text-color);
        text-align: center;
    }

    select {
        display: block;
        margin: 20px auto;
        font-size: 32px;
    }
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2267472.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

客户案例:基于慧集通的致远OA与海康威视智能会议设备集成方案

一、引言 本案例原型公司是我国生产纺织原料的大型上市企业&#xff0c;主导产品为再生纤维素长丝、氨纶等系列产品。公司产品不仅得到国内客户认可&#xff0c;还远销海外&#xff0c;合作伙伴遍布德国、意大利、日本、韩国、土耳其、印度等30多个国家和地区。 二、简介 &am…

【Leetcode】3046. 分割数组

文章目录 题目思路代码复杂度分析时间复杂度空间复杂度 结果 题目 题目链接&#x1f517; 给你一个长度为 偶数 的整数数组 n u m s nums nums 。你需要将这个数组分割成 n u m s 1 nums1 nums1 和 n u m s 2 nums2 nums2 两部分&#xff0c;要求&#xff1a; n u m s 1. l…

掌握软件工程基础:知识点全面解析【chap07、chap10】

chap07 软件设计基础 1.信息隐藏、内聚度和耦合度&#xff08;在七种级别里应该注意什么原则&#xff09;的概念 1.信息隐藏 模块独立的概念 o 模块应该设计得使其所含信息(过程和数据)对于那些不需要这些信息的模块不可访问; o 每个模块只完成一个相对独立的特定功能; o 模…

操作系统实验三 存储管理

实验三 存储管理 一、实验目的 通过实验使学生了解可变式分区管理使用的主要数据结构&#xff0c;分配、回收的主要技术&#xff0c;了解最优适应分配、最坏适应分配、最先适应分配和循环适应分配等分配算法。基本能达到下列具体的目标&#xff1a; 掌握初步进程在内存中的映…

40.2 预聚合和prometheus-record使用

本节重点介绍 : downsample降采样可以降低查询数据量 prometheus原生不支持downsample 实时查询/聚合 VS 预查询/聚合的优缺点 实时查询/聚合条件随意组合&#xff0c;性能差预查询/聚合 性能好&#xff0c;聚合条件需要提前定义 prometheus的预查询/聚合配置举例 downsample…

win11中win加方向键失效的原因

1、可能是你把win键锁了&#xff1a; 解决办法&#xff1a;先按Fn键&#xff0c;再按win键 2、可能是可能是 贴靠窗口设置 中将贴靠窗口关闭了&#xff0c;只需要将其打开就好了

【Rust自学】7.4. use关键字 Pt.2 :重导入与换国内镜像源教程

喜欢的话别忘了点赞、收藏加关注哦&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 7.4.1. 使用pub use重新导入名称 使用use将路径导入作用域内后。该名称在词作用域内是私有的。 以上一篇文章的代码为例&#xff1a; m…

算法练习——模拟题

前言&#xff1a;模拟题的特点在于没有什么固定的技巧&#xff0c;完全考验自己的代码能力&#xff0c;因此有助于提升自己的代码水平。如果说一定有什么技巧的话&#xff0c;那就是有的模拟题能够通过找规律来简化算法。 一&#xff1a;替换所有问号 题目要求&#xff1a; 解…

三层交换机配置

✍作者&#xff1a;柒烨带你飞 &#x1f4aa;格言&#xff1a;生活的情况越艰难&#xff0c;我越感到自己更坚强&#xff1b;我这个人走得很慢&#xff0c;但我从不后退。 &#x1f4dc;系列专栏&#xff1a;网路安全入门系列 目录 一&#xff0c;三层交换二&#xff0c;实验案…

TCP-UDP调试工具推荐:Socket通信测试教程(附详细图解)

前言 在网络编程与应用开发中&#xff0c;调试始终是一项不可忽视的重要环节。尤其是在涉及TCP/IP、UDP等底层网络通信协议时&#xff0c;如何确保数据能够准确无误地在不同节点间传输&#xff0c;是许多开发者关注的核心问题。 调试的难点不仅在于定位连接建立、数据流控制及…

登录时的校验Token接口开发(Interceptor)

// 拦截器校验所有非登录请求时的token&#xff0c;校验成功之后解析出用户信息存入ThreadLocal中便于本次请求中共享该用户的信息&#xff0c;这个信息只能在本线程中拿到 一、需求分析 在用户登录后的请求交互中&#xff0c;Token 的校验是保障用户身份合法性和数据安全的重…

Hyper-V如何将文件复制到虚拟机

创建Hyper-V共享文件夹 通过创建共享文件夹的方式&#xff0c;能够帮助我们在主机与虚拟机之间轻松地进行数据交换共享&#xff0c;那么具体该如何通过网络共享来将文件复制到虚拟机呢&#xff1f;请您接着往下看。 步骤1. 在Hyper-V主机中创建一个文件夹&#xff0c;并将您想…

Linux(Centos 7.6)yum源配置

yum是rpm包的管理工具&#xff0c;可以自动安装、升级、删除软件包的功能&#xff0c;可以自动解决软件包之间的依赖关系&#xff0c;使得用户更方便软件包的管理。要使用yum必须要进行配置&#xff0c;个人将其分为三类&#xff0c;本地yum源、局域网yum源、第三方yum源&#…

go语言中zero框架项目日志收集与配置

在 GoZero 项目中&#xff0c;日志收集和配置是非常重要的&#xff0c;尤其是在分布式系统中&#xff0c;日志可以帮助开发人员追踪和排查问题。GoZero 提供了灵活的日志系统&#xff0c;能够方便地进行日志的配置和管理。 以下是如何在 GoZero 项目中进行日志收集与配置的基本…

第4章 共享内存范式:基于R(Rdsm)的简单介绍

第4章 4.1 是什么被共享了&#xff1f; 4.1.1 全局变量 4.1.2 局部变量&#xff1a;栈结构 4.3 共享内存编程的高级介绍&#xff1a;Rdsm包 4.3.1 使用共享内存 4.4 示例&#xff1a;矩阵乘法 4.4.1 代码 4.4.2 分析 4.4.3 代码 4.4.4 详解我们数据的共享本质 4.4.5 计时…

optuna和 lightgbm

文章目录 optuna使用1.导入相关包2.定义模型可选参数3.定义训练代码和评估代码4.定义目标函数5.运行程序6.可视化7.超参数的重要性8.查看相关信息9.可视化的一个完整示例10.lightgbm实验 optuna使用 1.导入相关包 import torch import torch.nn as nn import torch.nn.functi…

SD ComfyUI工作流 对人物图像进行抠图并替换背景

文章目录 人物抠图与换背景SD模型Node节点工作流程工作流下载效果展示人物抠图与换背景 此工作流旨在通过深度学习模型完成精确的人物抠图及背景替换操作。整个流程包括图像加载、遮罩生成、抠图处理、背景替换以及最终的图像优化。其核心基于 SAM(Segment Anything Model)与…

【C语言程序设计——循环程序设计】利用循环求数值 x 的平方根(头歌实践教学平台习题)【合集】

目录&#x1f60b; 任务描述 相关知识 一、求平方根的迭代公式 1. 原理 2. 代码实现示例 二、绝对值函数fabs() 1. 函数介绍 2. 代码示例 三、循环语句 1. for循环 2. while循环 3. do - while循环 编程要求 测试说明 通关代码 测试结果 任务描述 本关任务&…

程序猿成长之路之设计模式篇——结构型设计模式

本篇开始介绍结构型设计模式 前言 与创建型设计模式用于创建对象不同&#xff0c;结构型设计模式通过结构化的方式实现功能的扩展和解耦&#xff0c;通过对象的组合、聚合、继承和接口等机制来定义对象之间的关系&#xff0c;从而实现松耦合和灵活性。 常见的结构性设计模式&…

低代码开源项目Joget的研究——Joget8社区版安装部署

大纲 环境准备安装必要软件配置Java配置JAVA_HOME配置Java软链安装三方库 获取源码配置MySql数据库创建用户创建数据库导入初始数据 配置数据库连接配置sessionFactory&#xff08;非必须&#xff0c;如果后续保存再配置&#xff09;编译下载tomcat启动下载aspectjweaver移动jw…