如何从父窗口访问同源iframe的window对象上挂载的自定义变量
根因说明
你遇到的现象是浏览器控制台对象懒求值导致的错觉:
- 父页面
DOMContentLoaded事件触发仅代表父页面自身的DOM解析完成,此时iframe内部的页面资源、脚本还未完成加载执行,courseData还没有被挂载到iframe的window对象上,直接访问自然返回undefined - 浏览器控制台打印对象时默认保存对象引用,你点击展开对象时才会读取对象的实时属性,此时iframe已经加载完成,所以能看到
courseData属性
解决方案
方案1:监听iframe的load事件(推荐)
iframe的load事件会在iframe内部所有资源加载、脚本执行完成后触发,此时再读取属性即可拿到正确值:
const iframe = document.getElementById("iframe"); // 监听iframe自身的加载完成事件,而非父页面的DOMContentLoaded iframe.addEventListener('load', () => { const iframeWindow = iframe.contentWindow; console.log(iframeWindow.courseData); })
方案2:新增轮询兜底
如果iframe内部是异步逻辑挂载courseData,load事件触发时也可能还未完成赋值,可以新增带超时的轮询逻辑兜底:
// 轮询查询属性,默认每100ms查一次,最多查20次(总超时2s) async function getIframeCourseData(maxRetry = 20, delay = 100) { const iframeWin = document.getElementById('iframe').contentWindow; for (let i = 0; i < maxRetry; i++) { if (iframeWin.courseData) { return iframeWin.courseData; } await new Promise(resolve => setTimeout(resolve, delay)); } throw new Error('获取iframe courseData超时'); } const iframe = document.getElementById('iframe'); iframe.addEventListener('load', async () => { try { const courseData = await getIframeCourseData(); console.log(courseData); // 后续业务逻辑 } catch (err) { console.error(err); } })
内容的提问来源于stack exchange,提问作者Cam Parry
相关产品推荐
相关产品推荐

