javascript對iframe的互操作淺析

[下面對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" οnblur="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" οnblur="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、通過iframe對象所在頁面的對象模型(通過document.getElementById("iframeId")獲取),你可以訪問iframe對象的屬性,但不能訪問其內容。
b、frames集合提供了對iframe內容的訪問(通過document.frames["iframeName"]獲取)。通常情況下我們都使用frames集合讀寫iframe內包含的元素。
c、如果只想改變iframe的src或者border, scrolling等attributes(與property不是一個概念,property是不能寫在標籤內的,比如:scrollHeight,innerHTML等),就需要用到document.getElementById方法.
d、要想使用iframe內的函數或dom元素(比如想得到iframe的document.body的內容),變量就必須通過frames集合.因爲它取的是一個完整的DOM模型,而通過id獲取的方法只是取出了一個object而已.
e、如果在iframe的頁面未完全裝載的時候,調用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事件改爲 οnblur="getAnotherChild()"就可以看到結果了.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章