繁体   English   中英

(盖茨比)数据包装器 iframe 在我刷新页面之前未显示

[英](Gatsby) Datawrapper iframes aren't displaying before I've refreshed the page

我正在使用Datawrapper在我的网站上将图形显示为 iframe。

我最近刚从 Remark 迁移到 MDX。 使用新设置,在允许以“传统”意义加载包含图表的页面之前(即点击刷新或直接关注包含图表的页面),我的 Datawrapper 图表不会加载。

因此,如果您点击此链接,图表显示正常: kolstadmagnus.no/ekspert-mener-a-ha-svaret-bak-krfs-stortingssmell

但是,如果您将 go 转到主页 ( kolstadmagnus.no ),然后点击链接(第二个顶部帖子),则不会显示图表。


一些上下文

Datawrapper iframe 使用此脚本,以便 iframe 响应:

!function(){"use strict";window.addEventListener("message",(function(e){if(void 0!==e.data["datawrapper-height"]){var t=document.querySelectorAll("iframe");for(var a in e.data["datawrapper-height"])for(var r=0;r<t.length;r++){if(t[r].contentWindow===e.source)t[r].style.height=e.data["datawrapper-height"][a]+"px"}}}))}();

由于 Gatsby 以它的方式工作(不是“传统地”加载每个页面——抱歉,我不知道这个功能叫什么),我不得不把这个脚本放在 html.js 文件中,如下所示:

<body {...props.bodyAttributes}>
  {props.preBodyComponents}
  <div
    key={`body`}
    id="___gatsby"
    dangerouslySetInnerHTML={{ __html: props.body }}
  />
  {props.postBodyComponents}
  <script
    dangerouslySetInnerHTML={{
      __html: `
            !function(){"use strict";window.addEventListener("message",(function(e){if(void 0!==e.data["datawrapper-height"]){var t=document.querySelectorAll("iframe");for(var a in e.data["datawrapper-height"])for(var r=0;r<t.length;r++){if(t[r].contentWindow===e.source)t[r].style.height=e.data["datawrapper-height"][a]+"px"}}}))}(); `
    }}
  />
</body>;

这会导致脚本针对整个网站而不是仅针对单个页面执行,从而解决了在使用 iframe 进入页面后需要点击刷新的问题。


但是,使用 MDX,问题又回来了。 但现在 iframe 根本不显示。

我该如何解决这个问题?

Gatsby 从@reach/router扩展了它的导航和它的“加载页面”,所以从 React。

我非常不鼓励在html.js的某些页面中嵌入需要呈现的自定义脚本,因为正如您所指出的,它将在全球范围内加载。 您可以通过在本地运行它或将其雾化来实现相同的效果。

您面临的问题是脚本直接指向 DOM(因为使用了window.addEventListener ),而在 React(因此使用 Gatsby)中,您创建和操作虚拟 DOM (vDOM)。 玩和操纵两者都可能导致误导性行为,因为一个人不知道另一个何时发生变化,反之亦然,破坏了水合作用和再水合作用过程(这就是为什么你会在刷新时看到结果:因为水合作用永远不会发生)。

也就是说,理想的解决方案是使用基于 React 的 Datawrapper 模块,如react-datawrapper-chart或使用其他自定义解决方案。 使脚本具有响应性并不是什么大问题,您可以使用基于 React 的代码进行相同的计算。

或者,按照您的“工作”方法,您可以使用特定页面上的Helmet组件加载自定义脚本:

const SomeSpecificPage = () =>{

return <>
   <Helmet>
    <script
       dangerouslySetInnerHTML={{
         __html: `
               !function(){"use strict";window.addEventListener("message", 
  (function(e){if(void 0!==e.data["datawrapper-height"]){var 
t=document.querySelectorAll("iframe");for(var a in e.data["datawrapper-height"])for(var r=0;r<t.length;r++){if(t[r].contentWindow===e.source)t[r].style.height=e.data["datawrapper-height"][a]+"px"}}}))}(); `
    }}
  />
   </Helmet>
</>

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM