Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何修复NextJS中的暗模式背景色闪烁?_Javascript_Reactjs_Next.js_Themes_User Experience - Fatal编程技术网

Javascript 如何修复NextJS中的暗模式背景色闪烁?

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

因此,我的问题是Next.js无法访问客户端的
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仪表盘在您未登录时避免在私人页面上闪烁的方式,这与您的问题完全相似:。这是一种客户机优先的方法,使用此方法可以稍微延迟渲染。