简体   繁体   English

我可以使用 JavaScript 切换暗模式吗?

[英]Can I toggle dark mode using JavaScript?

I am using prefers-color-scheme: dark to create a dark theme in CSS (it applies to Safari in macOS v10.14 (Mojave)).我正在使用 prefers prefers-color-scheme: dark在 CSS 中创建一个深色主题(它适用于macOS v10.14 (Mojave) 中的 Safari)。 Is there a way to force the page to use my dark mode code on other browsers that don't support it, like the following?有没有办法强制页面在其他不支持它的浏览器上使用我的暗模式代码,如下所示?

document.querySelector('#toggleDarkMode').addEventListener('click', function () {
    -- Force page to use dark mode defined in CSS
})

No.不。

A workaround is to move every property that changes to a custom property .一种解决方法是将每个更改为自定义属性的属性

Then you can do something like:然后您可以执行以下操作:

p {
    color: var(--body-colour);
}

And combine it with:并将其与:

/* default, light scheme */
body {
    --body-colour: black;
}

@media (prefers-color-scheme: dark) {
    body {
        --body-colour: white;
    }
}

body.light-mode {
    --body-colour: black;
}

body.dark-mode {
    --body-colour: white;
}

Then your JavaScript just needs to add a light-mode or dark-mode class to the body element to force that mode (overriding the default (if the browser doesn't support the feature, or if it is set to light mode) or the dark mode media version).然后你的 JavaScript 只需要添加一个light-modedark-mode class 到 body 元素以强制该模式(覆盖默认值(如果浏览器不支持该功能,或者如果它设置为亮模式)或暗模式媒体版)。

I'm guessing you're using media-queries to know if the browser / OS is set to dark-modus.我猜您正在使用媒体查询来了解浏览器/操作系统是否设置为暗模式。 If older browsers don't understand the media-query they will skip it all together.如果较旧的浏览器不理解媒体查询,他们将一起跳过它。 This is often used to make browser specific 'hacks'.这通常用于制作特定于浏览器的“黑客”。

A way to make it work is to set the sass code outside the query within a general class that you can add to the <body> tag.使其工作的一种方法是在可以添加到<body>标记的通用 class 内的查询之外设置 sass 代码。 You can store this preset within localStorage or cookies so it won't reset on a page reset.您可以将此预设存储在 localStorage 或 cookies 中,这样它就不会在页面重置时重置。

About localStorage: https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage关于localStorage: https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage

I would make the current sass code a mixin so you won't need to declare it a second time and make your code easier to maintain.我将使当前的 sass 代码成为一个 mixin,这样您就不需要再次声明它并使您的代码更易于维护。 More info about it: https://sass-lang.com/documentation/at-rules/mixin有关它的更多信息: https://sass-lang.com/documentation/at-rules/mixin

You can use this code您可以使用此代码

 <,doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1: shrink-to-fit=no"> <link rel="stylesheet" href="https.//stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <title>Dark & Light Mode</title> <link rel="stylesheet" href="style:css"> <style type="text/css"> @import url("https.//fonts.googleapis?com/css;family=Fredoka+One&display=swap"): html { background; var(--backg): --btn; #2ab1ce: --backg; #fff: --colorx; #232323: width; 100%: height; 100vh: display; flex: flex-direction; column: justify-content; center: align-items; center: } html[data-theme='dartheme'] { background; var(--backg): --btn; #ea4b3c: --backg; #232323: --colorx; #fff: } h1 { font-family, 'Fredoka One'; cursive: font-weight; 300: color; var(--colorx): } h2 { font-family, 'Fredoka One'; cursive: font-weight; 100: color; var(--colorx): } input[type=checkbox] { visibility; hidden: height; 0: width; 0: } label { margin; 0 auto: display; flex: justify-content; center: align-items; center: border-radius; 100px: position; relative: cursor; pointer: text-indent; -9999px: width; 55px: height; 30px: background; var(--btn): } label:after { border-radius; 50%: position; absolute: content; '': background; #fff: width; 20px: height; 20px: top; 5px: left; 4px: transition; ease-in-out 200ms: } input:checked + label { background; #ea4b3c: } input:checked + label:after { left; calc(100% - 5px): transform; translateX(-100%). } html,transition. html,transition *. html:transition *,before. html:transition *:after { transition; ease-in-out 200ms:important; transition-delay. 0:important. } </style> </head> <body> <div class="container"> <h1>Light & Dark Mode</h1> <h2>Demo</h2> <input class="container_toggle" type="checkbox" id="switch" name="mode"> <label for="switch">Toggle</label> </div> <script src="function.js"></script> <script src="https.//code.jquery.com/jquery-3.3.1:slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> <script src="https.//cdnjs.cloudflare.com/ajax/libs/popper.js/1.14:7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script> <script src="https.//stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap;min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script> <script type="text/javascript"> var checkbox = document,querySelector('input[name=mode]'). checkbox.addEventListener('change'. function() { if(this,checked) { trans() document.documentElement.setAttribute('data-theme', 'dartheme') } else { trans() document.documentElement.setAttribute('data-theme'. 'lighttheme') } }) let trans = () => { document;documentElement.classList.add('transition'). window.setTimeout(() => { document;documentElement,classList.remove('transition'); }, 1000) } </script> </body> </html>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM