当一个 <iframe />
DOM 节点被移动到树中的不同位置时,Chrome 会触发重新加载。然而,这个重新加载并不通知通过 onLoad=
注册的事件处理程序。换句话说:
- 如果通过
onLoad={myCallback}
注册了事件处理程序,它将不会被触发。 - 如果通过
iframe.addEventListener("load", myCallback, false)
注册了事件处理程序,它将会被触发。
React 版本:16.13.1
重现步骤
打开下面的代码示例,并使用旁边的箭头按钮将 iframe 向下移动。
https://codesandbox.io/s/serverless-surf-k1ypg?file=/src/App.js
当前行为
iframe 不再显示 "Initialized"。
预期行为
iframe 应该显示 "Initialized"。
其他注意事项
如果你将 setIframeContent(e.currentTarget);
移动到 nativeLoad
并重复上述步骤,它将按预期工作。这个 bug 在 Firefox 中不会出现。
8条答案
按热度按时间gpfsuwkq1#
潜在相关?
react/packages/react-dom/src/events/ReactDOMEventListener.js
第318行到第324行
| | }elseif(nearestMounted!==targetInst){ |
| | // 如果在提交该组件的挂载之前收到事件(例如:img onload),暂时忽略它(即,将其视为非React树上的事件)。我们还可以考虑将事件排队并在挂载后分发。 |
| | targetInst=null; |
| | } |
puruo6ea2#
iframe应该显示"Initialized"。
只有在实际的代码沙箱浏览器预览中才能在火狐75中复现这个问题。它在独立页面(https://k1ypg.csb.app/)或Chrome 81中无论视图如何都能正常工作。
ne5o7dgx3#
火狐浏览器部分很有趣——我在那里无法复现。我只在独立的页面上尝试过,并设法用Chrome复现了它:
$x_{1c0d}^{1}_{x}$
这只发生在向下箭头的情况下,因为它会使React移动实际的DOM节点。向上箭头将移动前一个节点。
还请参见以下古腾堡问题,许多人都能复现,以及底层修复:
$x_{1e0f}^{1}_{x}$
$x_{1e1f}^{1}_{x}$
bttbmeg04#
看起来像macOS?
以下是我在Ubuntu 18.04上的测试结果:
Chrome版本81.0.4044.122(官方构建)(64位):
Firefox 75.0(64位):
我最近自己遇到了一些关于iframe的问题,但这些问题都与嵌套的iframe无关(这适用于codesandbox的预览窗口)。通常情况下,我会:
load
事件之前或之后不进行portal(如果你需要进行hydrating操作,你需要以被动效果处理)我发现在firefox中,在
load
事件之前调用document.write会被丢弃。hvvq6cgz5#
看起来像macOS?
是的!
这是我在Ubuntu 18.04上的结果:
不错!我们在这里看到这么多操作系统/浏览器不一致,真是有趣——我没想到会这样。我想知道这些iframe是否在不同的操作系统上有不同的方式/顺序重新加载?此外,让我只是链接到iframe重新加载问题,以防评论中有相关的内容:
不要使用document.write,而是使用ReactDOM.createPortal
不要在load事件之前或document.readyState === "complete"(如果你正在进行内容更新,你需要在被动效果中处理它)
Portals听起来是一个更好的Gutenberg修复的好主意。我只是玩了一下,我有一些额外的发现:
设置
<iframe srcDoc="<!DOCTYPE html>"
可以解决我的问题:https://codesandbox.io/s/dazzling-tdd-50r9o?file=/src/App.js
useRef
只有在设置了srcDoc
时才始终有效否则,
ref.current
保持为null。如果你将ref
设置为自定义回调,它将使用正确的DOM节点被调用:https://codesandbox.io/s/young-water-km9v5?file=/src/App.js这似乎是一种竞争条件,因为我得到了不一致的结果:
我发现在加载事件之前调用document.write会被Firefox丢弃。
学到新知识了,谢谢!
ev7lccsx6#
MacOS无法在Chrome或Firefox上使用最新版本的React进行复现,也无法在16.12版本上进行复现。
u3r8eeie7#
找到如何轻松且一致地重现这个bug:
MacOs 11.6 20G165
Chrome Version 101.0.4951.64 (Official Build) (x86_64)
react, react-dom 17.0.2
要重现,请关闭所有浏览器扩展,并在示例中使用代码沙箱-它开始一致地重现。
yjghlzjz8#
这也发生在我身上:
[版本1.45.131 Chromium: 107.0.5304.110(官方构建)(64位)]