动态添加name=true属性到iframe后postMessage未定义错误求助
嘿,我来帮你理清楚这个问题的根源和解决办法!
首先,你的代码里有几个关键误区,导致win返回undefined:
混淆了iframe DOM元素和它的内部window对象
你写的window.iframe其实是获取到的id为iframe的DOM节点,而不是iframe内部的window对象。DOM节点上根本没有nametrue这个属性,所以自然返回undefined,调用postMessage就会报错。错误的属性访问方式(以及笔误)
你动态给iframe加了name=true属性,这里要注意:HTML属性值本质都是字符串,所以实际iframe的name是"true"。而true是JavaScript的关键字,不能用点语法(比如window.true)访问对象属性,必须用方括号语法window["true"]来获取对应name的iframe window对象。而且你代码里写的nametrue完全是错误的写法,和你设置的name属性不对应。
接下来给你几个可行的解决方案:
方案一:通过iframe DOM元素获取contentWindow(最稳妥)
直接获取iframe的DOM节点,然后通过contentWindow属性拿到它的内部window对象,这是最可靠的方式,不受name属性的影响:
<iframe src="crossdomain.com" id="iframe"></iframe> <script> // 获取iframe DOM元素 const iframeElement = document.getElementById('iframe'); // 动态设置name属性(明确为字符串) iframeElement.setAttribute('name', 'true'); // 监听iframe加载完成后再发送消息,避免未加载完成时无法访问contentWindow iframeElement.addEventListener('load', () => { const win = iframeElement.contentWindow; win.postMessage("statusPause", "othersite.com"); }); </script>
方案二:通过window[name]访问iframe的window对象
如果一定要用name属性来获取,因为name是"true"(关键字),必须用方括号语法:
<iframe src="crossdomain.com" id="iframe" name="true"></iframe> <script> // 等待iframe加载完成 window.addEventListener('load', () => { // 用方括号访问关键字属性名 const win = window["true"]; win.postMessage("statusPause", "othersite.com"); }); </script>
另外补充一点:你说控制台里window.iframe.true能正常操作,大概率是你在控制台里混淆了对象——window.iframe是DOM节点,它本身没有true属性,可能是你误操作把iframe的window对象赋值给了这个属性,或者浏览器的特殊行为导致的混淆,实际代码里不能这么写哦。
内容的提问来源于stack exchange,提问作者raghuak

