Javascript 如何将脚本添加到在每次加载页面时运行的gatsby页面?

Javascript 如何将脚本添加到在每次加载页面时运行的gatsby页面?,javascript,reactjs,dom,gatsby,Javascript,Reactjs,Dom,Gatsby,我正试图在《盖茨比》中的单个页面中添加一个自定义的砖石脚本。它对网格布局中元素的样式属性进行修改,但本质上,每次加载或调整页面大小时,脚本都需要执行它的操作 我试图通过在返回React组件的函数中的effect hook中要求脚本来实现这一点: // in 'page.js' export default () => { useEffect(() => { require('./scripts/masonry'); } return // b

我正试图在《盖茨比》中的单个页面中添加一个自定义的砖石脚本。它对网格布局中
元素的样式属性进行修改,但本质上,每次加载或调整页面大小时,脚本都需要执行它的操作

我试图通过在返回React组件的函数中的effect hook中要求脚本来实现这一点:

// in 'page.js'
export default () => {
    useEffect(() => {
        require('./scripts/masonry');
    }

    return // blah blah blah...
}
在脚本中,我将脚本需要执行的所有操作都放在一个名为
resizeral
的函数中,并将其附加到
窗口。onloadend
并将其添加到调整大小事件侦听器中:

// in the masonry script at the very bottom
window.onloadend = resizeAll;
window.addEventListener('resize', resizeAll);

但这不起作用,因为脚本似乎只在调整页面大小时运行,而在加载或导航到页面时不运行。我的怀疑是
window.onloadend
由于某种原因被盖茨比的功能破坏了,或者我没有正确使用它。任何帮助都将不胜感激。

您可以使用React Helmet将内容写入html页面
标记。此外,您还需要Gatsby的
with prefix
来解析脚本的路径,该脚本是Gatsby内置的

最有可能的是,您正在使用的盖茨比启动器已经设置了React Helmet(查看您的
package.json
)。如果是这种情况,只需将脚本放在项目的
/static/
文件夹中,然后在React中将脚本包括在页面的
中,如下所示:

import Helmet from "react-helmet";
import { withPrefix } from "gatsby";

<Helmet>
<script src={withPrefix('masonry.js')} />
</Helmet>

从“反应头盔”导入头盔;
从“盖茨比”中导入{withPrefix};

如果出于某种原因,您的盖茨比项目尚未设置React头盔,则您可以按照说明进行设置。

最简单、最干净的方法是使用
Gatsby browser.js
。盖茨比在那里提供了几个API,符合您的要求。从文件中:

onclientry
功能

(\uuuU2:emptyArg,pluginOptions:pluginOptions)=>未定义

在盖茨比浏览器运行时首次启动时调用

因此,根据您的代码,在您的
gatsby browser.js
中添加:

export const onClientEntry = () => {
    useEffect(() => {
        require('./scripts/masonry');
    }, [])
};
上述代码假定:

  • 该脚本属于您自己的项目
  • 砌体将添加到所有页面。如果您不想将其添加到整个站点。请参见下面的实现
如果上述方法不能按预期工作,或者你不希望它无处不在。我会尝试向原始的
useffect
钩子添加一个空的dep(
[]
),因为这是最接近
componentDidMount
生命周期的解决方法:

useEffect(() => {
    require('./scripts/masonry');
}, [])
如果脚本是外部的(第三方):


上面的代码只是一个初步的解决方法,在任何React应用程序中都应该避免使用
文档
和其他DOM变量,因为它们对浏览器性能有很大影响,您可以使用
useRef
钩子来做同样的事情。

事实证明我解决了这个问题!Hooks似乎没有起到作用,所以我在
gatsby浏览器的onrouteupdateexport中插入了
resizeral
函数


正如Ferran Buireu所说,这是一个解决办法,但我的站点非常小,到目前为止,我还没有注意到对性能的任何严重损害,但如果需要,我将稍后重建脚本…

谢谢您的回答!我尝试了这个,它看起来表现出了脚本在页面加载时不运行的相同行为。包括脚本,问题可能就在那里。
useEffect(() => { 
  const script = document.createElement('script') 
  script.async = true script.defer = true 
  script.src = 'https://your_script.com' 
  document.querySelector('ANY_UNIQUE_DIV').appendChild(script) 
}, [])