JavaScript iframe 相互操作指南:父页面与子页面通信

作者:闭包旅人

时间:2026-10-24

浏览:144

本文深入解析 JavaScript 中 iframe 的相互操作方法,涵盖父页面访问子页面、子页面反向操作父页面以及子页面间间接通信三种场景。重点讲解 document.getElementById 与 document.frames 集合的区别,以及如何在不同页面层级间安全获取和操作 DOM 元素,附带 ASP.NET 环境下的代码示例。

文章目录

iframe 基础与页面结构

iframe 元素可被视为嵌入在文档中的另一个文档,类似于浮动框架(frame)。关于 iframe 的操作一直是前端开发中的难点,网络上虽有许多相关介绍文章,但本文结合实践经验,整理并记录关键笔记,以便更清晰地理解其工作机制。


一、页面结构


本示例涉及三个页面:一个父页面和两个子页面。两个子页面分别嵌入在父页面的两个 iframe 元素中,形成嵌套结构。


1、父页面 MainForm.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="MainForm.aspx.cs" Inherits="Test.MainForm" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
   
<title></title>
</head>
<body>
   
<form id="form1" runat="server">
   
<div>
       
<ul>
           
<li>
                父页面(文本失去焦点可看结果):
<input id="txtParent" name="txtParent" type="text" value="parent" onblur="iframeTest()" />
           
</li>
           
<li>
               
<iframe src="FrameA.aspx" id="iframeA"></iframe>
           
</li>
           
<li>
               
<iframe src="FrameB.aspx" id="iframeB"></iframe>
           
</li>
       
</ul>
   
</div>

   
<script type="text/javascript">

       
function iframeTest() {

       
}

   
</script>

   
</form>
</body>
</html>

2、子页面 A

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="FrameA.aspx.cs" Inherits="Test.FrameA" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
   
<title></title>

   
<script type="text/javascript">

       
//子页面与父页面之间的操作  
       
function getParent() {

       
}

       
//当前子页面与另外一个子页面之间的操作
       
function getAnotherChild() {

       
}
   
</script>

</head>
<body>
   
<form id="form1" runat="server">
   
<div>
         子页面1(文本失去焦点可看结果):
<input id="txtUserName" name="txtUserName" type="text" value="jeff wong" onblur="getParent()" />
   
</div>
   
</form>
</body>
</html>

3、子页面 B

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="FrameB.aspx.cs" Inherits="Test.FrameB" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
   
<title></title>
</head>
<body>
   
<form id="form1" runat="server">
   
<div>
        子页面2(文本失去焦点可看结果):
<input id="txtUserNameB" name="txtUserNameB" type="text"  value="jeffery zhao"/>
   
</div>
   
</form>
</body>
</html>

父页面与子页面的相互操作

二、具体操作实现 1、父页面操作子页面 此操作需在父页面 MainForm.aspx 中实现。通过修改父页面的 JavaScript 函数 iframeTest,可以观察父页面如何获取并操作子页面的元素:

        function iframeTest() {
           
var frame1 = document.getElementById("iframeA");
           
var frame2 = document.getElementById("iframeB");

           
var frameA = document.frames["iframeA"]; //等价于 var frameAa = document.frames.iframeA;
           
var frameB = document.frames["iframeB"]; //等价于 var frameBb = document.frames.iframeB;

           
//**********************************************
            alert
(frame1 == frameA); //false
            alert
(frame2 == frameB); //false

            alert
(frame1.src); //FrameA.aspx
            alert
(frame1.location); //undefined
            alert
(frameA.src); //undefined

            alert
(frameA.location); //location
            alert
(frameA.document.location);

            alert
(frame1.document.body.innerHTML); //这里返回的是MainForm.aspx的body里的innerHTML
            alert
(frame1.document.documentElement.innerHTML); //这里返回的是MainForm.aspx的html里的innerHTML

            alert
(frameA.document.body.innerHTML); //这里返回的是FrameA.aspx的body里的innerHTML
            alert
(frameA.document.documentElement.innerHTML); //这里返回的是FrameA.aspx的html里的innerHTML

           
//**********************************************  
           
var childFrameDoc = undefined;

           
//取FrameA.aspx内的input文本
           
if (document.all) {//IE
                childFrameDoc
= frameA.document; //*** 如果是frame1,就取不到FrameA.aspx页面里的input ***
           
} else {//Firefox
                childFrameDoc
= frameA.contentDocument;
           
}
            alert
(childFrameDoc.body.innerHTML);

           
var childTxt = childFrameDoc.getElementById("txtUserName");
           
var childTxtByName = childFrameDoc.getElementsByName("txtUserName");

            alert
(childTxt == childTxtByName[0]); //true
            alert
(childTxt.value); //jeff wong
            alert
(childTxtByName[0].value); // jeff wong


           
//取FrameB.aspx内的input文本
            childFrameDoc
= undefined;
           
if (document.all) {//IE
                childFrameDoc
= frameB.document;
           
} else {//Firefox
                childFrameDoc
= frameB.contentDocument;
           
}
            alert
(childFrameDoc.body.innerHTML);

           
var childTxt = childFrameDoc.getElementById("txtUserNameB");
           
var childTxtByName = childFrameDoc.getElementsByName("txtUserNameB");

            alert
(childTxt == childTxtByName[0]); //true
            alert
(childTxt.value); //jeffery zhao
            alert
(childTxtByName[0].value); // jeffery zhao

       
}

小结: a、通过 document.getElementById("iframeId") 获取 iframe 对象后,可以访问该 iframe 对象的属性,但无法直接访问其内部内容。 b、使用 document.frames["iframeName"] 访问 frames 集合,可以获取 iframe 内部的内容。通常情况下,我们利用 frames 集合来读写 iframe 内包含的元素。 c、若仅需修改 iframe 的 src、border、scrolling 等属性(注意:attribute 与 property 不同,如 scrollHeight、innerHTML 等 property 无法直接写在标签内),则应使用 document.getElementById 方法。 d、若要调用 iframe 内部的函数或访问其 DOM 元素(例如获取 iframe 的 document.body 内容),必须通过 frames 集合。因为 frames 集合返回的是完整的 DOM 模型,而通过 ID 获取的仅仅是一个对象引用。 e、若在 iframe 页面未完全加载时调用其 DOM 模型,将会引发错误。 2、子页面操作父页面 以子页面 FrameA.aspx 为例。在子页面 A 中,通过函数 getParent 获取 MainForm.aspx 的 DOM 元素,随后即可按照常规方式操作这些 DOM 元素:

 

        //子页面与父页面之间的操作  
       
function getParent() {
           
if (self != top) {
               
var oDoc = top.parent.document;
                alert
(oDoc.body.innerHTML);
                alert
(oDoc.documentElement.innerHTML);
                alert
(oDoc.frames.length); //返回结果:2  表明父页面有两个iframe

               
//操作父页面的文本框
               
var oTxt = oDoc.getElementById("txtParent");
                alert
(oTxt.value);

           
}
           
else alert("不在框架中");
       
}

3、子页面操作子页面 此场景需借助父页面间接获取另一个子页面。仍以子页面 A 为例,通过父页面间接获取子页面 B,随后像正常操作 DOM 一样,由子页面 A 完成对子页面 B 的控制和操作。 需先修改 getAnotherChild() 函数:

 

        //当前子页面与另外一个子页面之间的操作
       
function getAnotherChild() {
            alert
(self.location.href); //当前页面的url

           
//通过父页面,间接获取另外一个子页面
           
if (self != top) {
               
var oDoc = top.parent.document;
               
var oAnotherFrame = oDoc.frames["iframeB"]; //返回另外一个iframe

                alert
(oAnotherFrame.location);
                alert
(oAnotherFrame.document.body.innerHTML);
                alert
(oAnotherFrame.document.documentElement.innerHTML);

               
var oTxt = oAnotherFrame.document.getElementById("txtUserNameB");
                alert
(oTxt.value); //jeffery zhao
           
}
       
}

注意:修改 getAnotherChild() 函数后,将子页面 A(FrameA.aspx)中 textUserName 的 onblur 事件更改为 onblur="getAnotherChild()",即可看到操作结果。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章