如何使用JavaScript检测暗模式?

kuuvgm7e  于 2023-02-11  发布在  Java
关注(0)|答案(8)|浏览(191)

Windows和macOS现在有黑暗模式。
对于CSS,我可以使用:

@media (prefers-dark-interface) { 
  color: white; background: black 
}

但我使用的是StripeElementsAPI,它将颜色放入JavaScript中
例如:

const stripeElementStyles = {
  base: {
    color: COLORS.darkGrey,
    fontFamily: `-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"`,
    fontSize: '18px',
    fontSmoothing: 'antialiased',
    '::placeholder': {
      color: COLORS.midgrey
    },
    ':-webkit-autofill': {
      color: COLORS.icyWhite
    }
  }
}
    • 如何在JavaScript中检测操作系统的首选配色方案?**
at0kjp5o

at0kjp5o1#

if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
    // dark mode
}

要监视更改:

window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => {
    const newColorScheme = event.matches ? "dark" : "light";
});
7bsow1i6

7bsow1i62#

您可以直接使用JavaScript检查CSS Media-Queries
window.matchMedia()方法返回一个MediaQueryList对象,表示指定CSS媒体查询字符串的结果。matchMedia()方法的值可以是CSS @media规则的任何媒体特性,如最小高度、最小宽度、方向等。
要检查Media-Query是否为true,可以使用matches属性

// Check to see if Media-Queries are supported
if (window.matchMedia) {
  // Check if the dark-mode Media-Query matches
  if(window.matchMedia('(prefers-color-scheme: dark)').matches){
    // Dark
  } else {
    // Light
  }
} else {
  // Default (when Media-Queries are not supported)
}

要根据用户的首选项动态更新color-scheme,可以使用以下代码:

function setColorScheme(scheme) {
  switch(scheme){
    case 'dark':
      console.log('dark');
      
      break;
    case 'light':
      console.log('light');
      // Light
      break;
    default:
      // Default
      console.log('default');
      break;
  }
}

function getPreferredColorScheme() {
  if (window.matchMedia) {
    if(window.matchMedia('(prefers-color-scheme: dark)').matches){
      return 'dark';
    } else {
      return 'light';
    }
  }
  return 'light';
}

function updateColorScheme(){
    setColorScheme(getPreferredColorScheme());
}

if(window.matchMedia){
  var colorSchemeQuery = window.matchMedia('(prefers-color-scheme: dark)');
  colorSchemeQuery.addEventListener('change', updateColorScheme);
}

updateColorScheme();
ljo96ir5

ljo96ir53#

根据MediaQueryList - Web API|MDN,addListener是倾听变化的正确方式,addEventListener在iOS 13. 4上对我不起作用。

window.matchMedia('(prefers-color-scheme: dark)').addListener(function (e) {
  console.log(`changed to ${e.matches ? "dark" : "light"} mode`)
});
z9zf31ra

z9zf31ra4#

选中matchMedia选项:

function getTheme() {
  if(window.matchMedia && window.matchMedia("(prefers-color-scheme:dark)").matches) {
    return "dark";
  } else {
    return "light";
  }
}
klsxnrf1

klsxnrf15#

下面是一个基于SanBen's answer的一行程序:

const getPreferredScheme = () => window?.matchMedia?.('(prefers-color-scheme:dark)')?.matches ? 'dark' : 'light';
nwnhqdif

nwnhqdif6#

键入JavaScript之前:

你可以使用CSS来做一个@media查询,要求在body元素上有一个::after伪类,根据用户的配色方案有不同的文本。为了确保body元素上的::after不会让用户混淆,在after元素上添加一个display: none;

CSS代码:

@media (prefers-color-scheme:dark){
    body::after{
        content: 'd';
        display: none;
    }
}
@media (prefers-color-scheme:light){
    body::after{
        content: 'l';
        display: none;
    }
}

现在来看看您的JavaScript:

因为我们在文档中有一个对象要选择,我们可以得到body元素的::after伪类,我们需要得到它的内容,只要确保CSS在JavaScript之前加载! 'd'用于dark模式,'l'用于llight模式。

JavaScript代码:

var colorScheme = getComputedStyle(document.body,':after').content;
// d for dark mode, l for light mode.

为什么这会有用

你可以用CSS和HTML来做这件事,但是为什么要用JavaScript呢?
使用JavaScript是因为可能需要添加一个img元素,但图像中包含文本,因此有两个图像,一个用于浅色模式,另一个用于深色模式。因此,可以使用JavaScript将img元素的src属性值更改为基于配色方案的正确URL。
可能还有更多的用途,但那是我能想到的用途。

来源:

我从这篇stackoverflow文章中学习了getComputedStyle函数。
我学习了@media (prefers-color-scheme: * 配色方案,以便从MDN Web Docs中检测 * )
当我键入getComputedStyle(document.body,':after')时,我将其视为VSCode上的代码建议,从而学习了如何获得计算样式的.content,它的工作方式与我预期的一致(如果我在一篇文章中看到它,我找不到我访问过的文章)

3b6akqbq

3b6akqbq7#

对于使用React的人,请参见X1 E0 F1 X钩子。它监听更改,也允许您切换/更改黑暗模式。

import { useDarkMode } from 'usehooks-ts'

export default function Component() {
  const { isDarkMode, toggle, enable, disable } = useDarkMode()
  return (
    <div>
      <p>Current theme: {isDarkMode ? 'dark' : 'light'}</p>
      <button onClick={toggle}>Toggle</button>
      <button onClick={enable}>Enable</button>
      <button onClick={disable}>Disable</button>
    </div>
  )
}
soat7uwm

soat7uwm8#

如果您使用nuxt开发应用,则需要color-mode

相关问题