Javascript 如何修复NextJS中的暗模式背景色闪烁?
因此,我的问题是Next.js无法访问客户端的Javascript 如何修复NextJS中的暗模式背景色闪烁?,javascript,reactjs,next.js,themes,user-experience,Javascript,Reactjs,Next.js,Themes,User Experience,因此,我的问题是Next.js无法访问客户端的localStorage,因此将提供默认情况下具有或不具有class=“dark”的HTML 这意味着,当用户重新加载页面时,短暂没有class=“dark”,在一些javascript执行之前,会导致背景色闪烁,并将class=“dark”添加到。如果我随class=“dark”一起发送HTML,同样的问题也会发生,但情况正好相反:在class=“dark”从中删除之前,浅色模式的用户将体验到深色背景的闪光 有没有办法在页面呈现之前执行一些java
localStorage
,因此将提供默认情况下具有或不具有class=“dark”
的HTML
这意味着,当用户重新加载页面时,
短暂没有class=“dark”
,在一些javascript执行之前,会导致背景色闪烁,并将class=“dark”
添加到
。如果我随class=“dark”
一起发送HTML,同样的问题也会发生,但情况正好相反:在class=“dark”
从
中删除之前,浅色模式的用户将体验到深色背景的闪光
有没有办法在页面呈现之前执行一些javascript?然后,我可以根据用户的
localStorage
添加或不添加class=“dark”
到
中。当然,可以使用以下内容将noflash.js
文件添加到公共目录中
(函数(){
//如果你在钩子里使用了不同的东西,就改变这些。
var storageKey='darkMode';
var classnameduck=‘暗模式’;
var classNameLight='灯光模式';
函数集ClassOnDocumentBody(暗模式){
document.body.classList.add(深色模式?classNameDark:classNameLight);
document.body.classList.remove(深色模式?classNameLight:classNameDark);
}
var preferDarkQuery='(首选颜色方案:深色)';
var mql=window.matchMedia(preferDarkQuery);
var supportsColorSchemeQuery=mql.media==preferDarkQuery;
var localStorageTheme=null;
试一试{
localStorageTheme=localStorage.getItem(storageKey);
}捕获(错误){}
var localStorageExists=localStorageTheme!==null;
if(localStorageExists){
localStorageTheme=JSON.parse(localStorageTheme);
}
//确定真相的来源
if(localStorageExists){
//来自本地存储的真相来源
setClassOnDocumentBody(localStorageTheme);
}else if(支持颜色方案){
//系统的真理之源
setClassOnDocumentBody(mql.matches);
setItem(storageKey,mql.matches);
}否则{
//来源于document.body
var isDarkMode=document.body.classList.contains(classnameduck);
setItem(storageKey,JSON.stringify(isDarkMode));
}
})();
// https://github.com/donavon/use-dark-mode/blob/develop/noflash.js.txt
然后,将以下scriptsrc
标记添加到pages/\u文档文件的Head
类中包装的返回内容中
import Document, {
Head,
Html,
Main,
NextScript,
DocumentContext
} from 'next/document';
class MyDocument extends Document {
static async getInitialProps(ctx: DocumentContext) {
const initialProps = await Document.getInitialProps(ctx);
return { ...initialProps };
}
render() {
return (
<Html lang='en-US'>
<Head>
<meta charSet='utf-8' />
<script type="text/javascript" src='/noflash.js' />
</Head>
<body className='loading'>
<Main />
<NextScript />
</body>
</Html>
);
}
}
export default MyDocument;
然后,在pages/\u文档中更改以下脚本标记,如下所示
之前
//
//
之后
//
//
(从2020年秋季开始,在tailwindcss构建暗模式支持之前)当然可以使用next.js预渲染页面(SSR),但您是否愿意放弃所有CSR好处?您不应该将此信息存储在本地存储中,而是存储在cookie中,这是在所有请求旁边传递信息,从而使服务器端渲染按预期工作的唯一方法。这还意味着添加一个getServerSideProps
来解析cookie并将颜色值作为props传递,或者在\u app
中添加getInitialProps
。我已经写了一个建议,让这样的用例仅在静态呈现时成为可能:。另外,为了更直接地回答这个问题,是的,这是可能的,您可以在页面呈现之前运行纯JS脚本。这就是Vercel仪表盘在您未登录时避免在私人页面上闪烁的方式,这与您的问题完全相似:。这是一种客户机优先的方法,使用此方法可以稍微延迟渲染。