iframe.src = 'javascript:false' 必须在 remove() 前执行,否则残留文档、js 环境、定时器和监听器;需同步置空 contentwindow 引用并解绑事件,老 sdk 需手动清理定时器、监听器和 observer。

iframe.src = 'javascript:false' 必须在 remove() 之前执行
直接 iframe.remove() 或设 src = '' 只是删 DOM 节点,内部文档、JS 执行环境、全局定时器、事件监听器全还在。多数第三方地图/图表 SDK(如 BMap、AMap、ECharts)会在 document.open(); document.close(); 时触发内部 destroy() 流程——而 src = 'javascript:false' 正是可靠触发该流程的最小代价方式。
常见错误:
- 顺序颠倒:先
remove()再设src,等于没做清理 - 用
innerHTML = ''或display: none替代移除,DOM 节点仍在,GC 不会回收任何内容 - 在 IE/Edge Legacy 中误用
src = 'about:blank':它不强制重置 JS 上下文,残留资源持续驻留
contentWindow 引用必须显式置空
只要父页面还持有 iframe.contentWindow 的引用(比如缓存到 this.iframeWin、传给闭包、绑定到定时器回调),哪怕 iframe 已从 DOM 移除,其内部 HTMLDocument 就会变成 Detached HTMLDocument,永远无法被 GC 回收。
验证方式:Chrome Memory 面板拍对比快照 → Comparison 视图筛选 Detached HTMLDocument → 看 Retainers 是否指向 Closure → function → iframeWin。
实操要点:
- 销毁前必须执行
iframeWin = null(或delete this.iframeWin) - 若曾用
iframe.contentWindow.addEventListener('message', handler),需同步调用iframe.contentWindow.removeEventListener('message', handler) - 跨域 iframe 的
postMessage监听器绑在window上时,必须在移除前调用window.removeEventListener('message', handler)
老 SDK 没 destroy 接口?手动清理三件套
百度地图 v1.x、Highcharts v3、ECharts v2.2.7 这类老版本压根不暴露销毁方法,仅靠 src = 'javascript:false' + remove() 不够。必须进入子环境主动干预。
在 setTimeout(() => { }, 0) 或 requestAnimationFrame 回调中操作(确保文档已重置完成):
- 清除所有定时器:
iframe.contentWindow.clearInterval(id)、clearTimeout(id)(需提前缓存 ID) - 解绑监听器:
iframe.contentWindow.removeEventListener('resize', fn)、iframe.contentWindow.document.removeEventListener('scroll', fn) - 断开 Observer:
iframe.contentWindow.IntersectionObserver?.disconnect()、MutationObserver?.disconnect() - 清空 Canvas:
ctx.clearRect(0, 0, canvas.width, canvas.height),再设canvas.width = canvas.height = 0
IE 下额外补一刀:CollectGarbage() 和 removeNode(true)
IE8 及更老版本中,remove() 不等价于彻底卸载;CollectGarbage() 虽然只 IE 支持且效果不稳定,但在确定上下文已清空后调用一次,仍有实际释放作用。
关键细节:
-
removeNode(true)比remove()更彻底,尤其对动态创建的 iframe -
CollectGarbage()必须在iframe.contentWindow.close()之后、removeNode()之前调用 - 不要在现代浏览器里用
CollectGarbage(),它会抛错
最易被忽略的是:延迟清理的时机。不加 setTimeout 或 requestAnimationFrame,contentWindow 可能仍是 null 或未就绪,后续所有清理操作都静默失败。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











