使用JavaScript访问iframe内元素异常,为何获取的a标签数量为0?
iframe获取子页面元素返回0的问题分析
场景复现
测试文件如下:
MyFrame.HTML
<!DOCTYPE html> <html> <head> <title>My Frame</title> </head> <body> <a href="https://www.google.com">Google</a><br /> <a href="https://www.bingle.com">Bingle</a><br /> </body> </html>
MyPage.HTML
<!DOCTYPE html> <html> <head> <title>My Page</title> </head> <body> <iframe src="MyFrame.HTML" loading="eager" id="MyFrame123"></iframe> </body> <script> //does this script run after MyFrame is loaded? setTimeout(function () { var frmDoc = document.getElementById("MyFrame123"); if (frmDoc != null) { var n = frmDoc.getElementsByTagName("A").length; console.log(n); //n==0, why? } else console.log("no frmDoc"); }, 5000); </script> </html>
设置5秒延迟执行脚本后,控制台输出n的值为0,原因如下:
问题根源
document.getElementById("MyFrame123")获取到的是iframe DOM元素本身,而非iframe内部的文档对象。在这个iframe元素上调用getElementsByTagName("A"),只会查找该元素自身的直接子节点(也就是iframe的备用内容,这里为空),自然返回长度为0的元素集合。
修正方案
要访问iframe内部的页面内容,必须通过iframe元素的contentDocument属性(标准浏览器支持)或contentWindow.document(兼容旧版IE)获取内部文档对象,再进行元素查询:
修正后的脚本代码
<script> setTimeout(function () { var frmElement = document.getElementById("MyFrame123"); if (frmElement != null) { // 获取iframe内部的文档对象 var frmDoc = frmElement.contentDocument || frmElement.contentWindow.document; var n = frmDoc.getElementsByTagName("A").length; console.log(n); // 此时输出2 } else console.log("no frmDoc"); }, 5000); </script>
更可靠的写法(监听load事件)
依赖固定延迟的方式并不稳定,最好监听iframe的load事件,确保页面完全加载后再执行操作:
<script> var frmElement = document.getElementById("MyFrame123"); frmElement.addEventListener('load', function() { var frmDoc = frmElement.contentDocument || frmElement.contentWindow.document; var n = frmDoc.getElementsByTagName("A").length; console.log(n); }); </script>
内容的提问来源于stack exchange,提问作者Eses
相关产品推荐
相关产品推荐

