下一个JS:当dom渲染时加载屏幕

问题描述 投票:0回答:9

如何显示我自己的加载程序而不是空白屏幕? 例如,Tweeter 在页面加载时显示徽标,Facebook、谷歌 AdSense 等也是如此。 看这个 Gif,我想要在 Next Js 中出现类似的东西。

我猜这与 _document.js 有关。 React js 有一个类似的问题(在index.html 中渲染加载器) 但我不知道如何在下一个js中做到这一点。

javascript reactjs dom next.js server-side-rendering
9个回答
9
投票

要在 Nextjs 上添加启动屏幕,您可以通过多种方式完成。这是我首选的解决方案。

/**
 * inside _app.js function for remove the loader
 */
useEffect(() => {
  if (typeof window !== 'undefined') {
    const loader = document.getElementById('globalLoader');
    if (loader)
      loader.remove();
  }
}, []);
/* Style.css or global.css */

#globalLoader {
  position: fixed;
  z-index: 9999;
  top: 50%;
  left: 50%;
  background-color: #fff;
  transform: translate(-50%, -50%);
  width: 100%;
  height: 100%;
  justify-content: center;
  align-items: center;
  display: flex;
}
/** * on _document.js insert below code after body tag * More about _document.js -> https://nextjs.org/docs/advanced-features/custom-document */

<div id="globalLoader">
  <img src="https://upload.wikimedia.org/wikipedia/commons/b/b1/Loading_icon.gif" alt="" />
</div>


4
投票

通常这些是通过一个覆盖所有内容并默认显示的 div 来完成的,您在该 div 中放置的内容取决于您(gif、svg 等)。一旦 window.onload 被调用,只需隐藏 div,它将显示完全渲染的 dom。

这是一个基本示例(我在移动设备上,请原谅我的格式) CSS:

.loadingsScreen{
        position:absolute;
        left:0;
        top:0;
        width:100%;
        height:100%;
        background-color: #whatever-color;
        z-index: 10;  /*just make sure it's the highest on the page*/
}

JS:

window.onload = function(){
        $("#loadingScreen").fadeOut(); //just make it hide the overlaying div, I used jQuery in this example but there are many ways to do this
};

2
投票

无需安装任何库

import { useRouter } from "next/router";
import { useState, useEffect } from "react";

function MyApp() {
  const router = useRouter();
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    router.events.on("routeChangeError", (e) => setLoading(false));
    router.events.on("routeChangeStart", (e) => setLoading(false));
    router.events.on("routeChangeComplete", (e) => setLoading(true));

    return () => {
      router.events.off("routeChangeError", (e) => setLoading(false));
      router.events.off("routeChangeStart", (e) => setLoading(false));
      router.events.off("routeChangeComplete", (e) => setLoading(true));
    };
  }, [router.events]);

  return <>{loading ? "loading..." : <AppComponent />}</>;
}

1
投票

使用suspense,nextjs支持它,但在使用它之前有事情值得考虑。

假设您正在使用带有应用程序目录的 NextJs 13:

在应用程序目录中创建一个文件loading.js或任何名称。这将是您在 DOM 渲染时显示的布局,按照您想要的方式设计它,放置任何需要的 gif/svgs。

loading.js

export default function Loading() {
    return (
        <div className="fixed inset-0 bg-blue-500 z-[10000] flex flex-1 items-center justify-center">
        Loading
        </div>
    );
}

那么你的布局文件应该如下所示:

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        <Suspense fallback={<Loading />}>{children}</Suspense>
      </body>
    </html>
  );
}

只要你的 DOM 被渲染消失,你就会看到它在某些上像 fla 一样渲染,而在另一些上则很慢,这取决于你的页面大小。如果需要,您可以查找、延迟 Suspense 或添加惰性组件。

提示:使用 Lottie 动画来制作加载或任何较小尺寸的 svg,并且旋转使用 css 动画来保持悬念内容更小。


0
投票

实际上这不是 Next.js 提供的“开箱即用”的东西,你必须自己实现这些东西,你可以使用一些全局状态(redux/context)来确定你的应用程序是否正在加载某些东西,并基于渲染加载器就这个状态。


0
投票

试试这个逻辑。创建一个状态变量并使用 NextJs Router 事件。使用路由器事件来控制状态变量,最后使用状态变量来控制加载屏幕和其他 DOM 元素的渲染。

   function MyApp(){
     const [loading, setLoading] = React.useState<boolean>(false);

     Router.events.on('routeChangeStart', (url) => {
       setLoading(true);
      });

     Router.events.on('routeChangeComplete', (url) => {
       setLoading(false);
     });
    

    return(
      <>
        {loading ? (
            <PageLoader />
          ) : (
            <AppLayout>
              <Component {...pageProps} />
            </AppLayout>
          )}
    </>
  )
}

0
投票

如果您使用的是 next js 13 应用程序路由器,您可以简单地添加一个“loading.js”(如果您将此文件命名为任何其他名称,它将不起作用,它应该是 load.js || ts 由 next.js 保留)文件在应用程序文件夹中并添加您想要的任何类型的加载动画或图像。


-1
投票

你不能。您看到的是 twitch 加载程序向您显示的自定义启动屏幕。它的作用是将加载过程分为两部分。第一个是标准的 - 浏览器请求并接收您提供的用于呈现页面的 html 和脚本文件。您无法使用传统的 Web 应用程序绕过此阶段,但是为了改善用户体验,您可以做的是最大限度地减少该时间。一个很好的例子是一个包含内联 css 和 javascript 的 index.html,它们可以为启动屏幕设置动画,一旦加载就会启动实际的应用程序。这样,真正的数据交换是在浏览器呈现页面之后完成的。这需要您在规划应用程序时做大量工作,但使用现代框架和工具肯定有更短、更脏的路径来实现它。然而,如果您有 SPA,这几乎是您唯一可以选择的方法。

顺便说一句,如果您想加快网站的加载速度(这就是为什么需要启动屏幕),只需运行一些分析,检查优化即可。服务器端缓存通常可以为您提供最佳的投资回报率,但它不会帮助您处理较重的负载(大图像或大量小图像)。 html 分段是第二好的选择。然后你应该看看导入的库和东西,这些往往会增加一些。最后还有一些选项可以压缩服务器上的数据以限制数据负载。


-1
投票

您可以使用router.event。

请参阅此链接:

https://github.com/vercel/next.js/blob/canary/examples/with-loading/pages/_app.js

useEffect(() => { const handleStart = (url) => { 控制台.log(

Loading: ${url}
) NProgress.start() } 常量handleStop = () => { NProgress.done() }

router.events.on('routeChangeStart', handleStart)
router.events.on('routeChangeComplete', handleStop)
router.events.on('routeChangeError', handleStop)

return () => {
  router.events.off('routeChangeStart', handleStart)
  router.events.off('routeChangeComplete', handleStop)
  router.events.off('routeChangeError', handleStop)
}

},[路由器]);

© www.soinside.com 2019 - 2024. All rights reserved.