Javascript 在 Gatsby 中呈现页面之前工作

Javascript working before page rendering in Gatsby

我尝试将 HTML template (Bootstrap 5) 转换为 Gatsby 模板。 CSS 和页面正常工作,但在 HTML 模板中有一个 main.js 文件,它需要在页面呈现后加载。

我这样修改main.js文件;

import { Swiper } from "swiper/swiper-react.cjs.js";
import GLightbox from "glightbox/dist/js/glightbox.min.js";
import AOS from "aos";
AOS.init();

export const onClientEntry = () => {
  window.onload = () => {
    console.log("deneme");
    /*rest of code*/
  };
};

这里我尝试两种方式。其中之一,我在 src->components->assets->js 文件夹中创建 main.js 文件。然后在 layout.js 我尝试导入那个文件。

import React from "react";
import PropTypes from "prop-types";
import { Breadcrumb } from "gatsby-plugin-breadcrumb";
import Header from "./partials/header";
import { Helmet } from "react-helmet";
import useSiteMetadata from "./hooks/siteMetadata";

import "./assets/css/style.css";
import "./assets/js/main.js"

但是在调试中没有命中onClientEntry 中的任何方法。所以我决定改变我的方式。

其次,我尝试将main.js中的代码添加到gatsby-browser.js。由于 html 尚未准备好,又到了 Cannot read property 'addEventListener' of null 的时候了。

我的文件结构:

window (and other global objects like document) are not available during the SSR (Server-Side Rendering) because this action is performed by the Node server (where for obvious reasons there's no window, yet) so you can't access directly to onload function. In addition, accessing these global objects outside the scope of React (without hooks) can potentially break React's hydration 进程。

也就是说,您有几种方法:

  • 使用 React 挂钩。具体来说,具有空依赖项 ([]) 的 useEffect 符合您的规范,因为一旦加载 DOM 树(这就是空 deps 的意思)就会触发效果:

    const Layout = ({children}) => {
    
       useEffect(()=>{
         mainJs();
       }, [])
    
       return <main>{children}</main>
    }
    
    

    假设您的 ./assets/js/main.js 文件导出了 mainJs() 函数,此方法将在加载 DOM 树时加载它。例如:

    const mainJs= ()=> console.log("deneme");
    

    浏览器构建HTML树时会触发console.log()。调整它以适应您的需要。

  • 添加 window-可用性条件,例如:

    export const onClientEntry = () => {
       if(typeof window !== 'undefined'){
          window.onload = () => {
            console.log("deneme");
            /*rest of code*/
          };
        }
    };
    

    或者,您可以根据需要直接在 onClientEntry 中输出 console.log

    export const onClientEntry = () => {
      console.log("deneme");
      /*rest of code*/
    };
    

您甚至可以通过在您的 gatsby-browser 中添加 useEffect 来结合这两种方法,如果它适合您的话。