IFrame事件监听中baseURI异常:获取旧版本URL问题
问题分析与解决
你的代码存在两个核心问题,导致无法获取最新的iframe baseURI:
- 移除事件监听时传入了新的空函数,和添加的回调不是同一个实例,旧的监听根本没被清理。当
dependency变化触发新的useEffect时,旧监听仍绑定在iframe上,触发时会用旧闭包里的iFrameRef,自然拿到旧地址。 - 回调里依赖
iFrameRef.current,但闭包会捕获初始的ref引用,即使ref后续更新,旧回调里的还是老值。
修正方案1:用事件对象的target获取当前iframe
直接在load回调里通过event.target拿到加载完成的iframe实例,彻底避开闭包问题:
useEffect(() => { const iframe = iFrameRef.current; if (!iframe) return; const handleLoad = (event) => { const currentIframe = event.target; console.log('CURRENT', currentIframe.baseURI); }; iframe.addEventListener('load', handleLoad); return () => { iframe.removeEventListener('load', handleLoad); }; }, [dependency]);
修正方案2:确保监听函数正确清理+使用当前周期的iframe引用
如果一定要依赖iFrameRef,可以直接使用当前useEffect周期里的iframe变量,同时保证监听函数唯一且被正确移除:
useEffect(() => { const iframe = iFrameRef.current; if (!iframe) return; const handleLoad = () => { console.log('CURRENT', iframe.baseURI); }; iframe.addEventListener('load', handleLoad); return () => { iframe.removeEventListener('load', handleLoad); }; }, [dependency]);
额外注意
如果iframe是动态修改src的,要确保每次dependency变化时,iframe的src确实完成了更新,否则load事件可能不会触发。另外,部分场景下iframe的load事件会多次触发(比如内部跳转),若只需要最终地址,可以考虑改用DOMContentLoaded事件,或者添加防抖处理。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

