[ASP.net WebForm] 由父視窗設定iframe自動高度

set iframe auto height in ASP.net WebForm

前言

從父視窗設定iframe自動高度網路上雖然一堆文章

但很多都是設定iframe.contentDocument.body.offsetHeight或iframe.contentWindow.document.body.scrollHeight

最近開發ASP.net WebForm,發現網頁一經過PostBack後body高度就無法縮矮回去

所以若照著上述設定iframe高度(使用iframe底下的body高度),網頁只會愈變愈長

而且看了很多文章都採用原生JS寫法,可能那些寫法年代久遠,某些註冊事件的程式碼不會在Chrome瀏覽器觸發

經過一天試來試去,終於試出在ASP.net WebForm裡讓iframe自動高度的完美解決方案

有以下幾個要點:

1.使用jQuery來註冊事件最靠譜

2.不要抓iframe裡body的高度,要抓的應該是iframe裡的form高度

3.抓Height高度使用jQuery的.height()最靠譜,不使用原生Javascript的scrollHeight或offsetHeight

實作

1.新增jquery.autoheight.js檔


function doIframe() {
    
    $("iframe").each(function () {
        let $oIframe = $(this);   
        //判斷需要自動高度的iframe
        if ($oIframe.hasClass("autoHeight")) 
        {//有滿足className 
             
            //使用jQuery來註冊事件最靠譜
            $oIframe.on("load",function(){
                //console.log('iframe load');
                setHeight($oIframe); 
            });    
              
        }//end if  
    });//end each
     
}//end function

function setHeight($oIframe) { 
    //最後要給iframe的height
    let height = 0; 
     
    //直接用$oIframe.find("body form:first");會抓不到iframe網頁的元素
    //必須先透過.contents()取得iframe網頁內容 
      let $form = $oIframe.contents().find("body form:first");//抓iframe網頁的第一個form(ASP.net WebForm一個網頁只能有一個form元素)
      if ($form.length > 0)  //有抓到form元素
      {  
          height = $form.height();//取得表單高度,並給值,因為ASP.net Web Form一經postback後,body高度就無法縮小,所以改抓form高度
        
      }//end if 

    //height太小的話,要給固定高度,避免Bug(例如:滑出的選單被蓋住)
    if (height < 800)
    {
        height = 800;
    }//end if 

    //最後算出來的height
     //console.log(height);
    //設定高度(CSS下滑動畫)
    $oIframe.animate({ height: height });
   
}
 
//父視窗DOM Ready
jQuery(function(){
    doIframe();
});

2.網頁的使用↓

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

<!DOCTYPE html>
<html>
<head> 
        <meta charset="UTF-8" />
        <!--裝置寬度-->
        <meta name="viewport" content="width=device-width" />
        <!--強制IE使用最新文件模式-->
        <meta http-equiv="X-UA-Compatible" content="IE=edge" /> 

		<title>Demo Title</title> 
</head>
    <body>
        <form id="form1" runat="server">
        <div>
            <a href="/testWeb/test.aspx">Click me</a>
        </div> 

        <!--加上class name:autoHeight,指示自訂的JS此iframe要處理自動高度-->
        <iframe class="autoHeight" src="null.html" 
             style="width:100%;height:800px;border-width:0px;" scrolling="no"  >
        </iframe>
      <!--iframe記得加上</iframe>標籤,否則之後的元素都會被iframe內容清除--> 
		<!--預設高度800px-->
        
        <!--引用jQuery-->
        <script src="JS/jquery-3.2.1.js"></script>
        <!-- 引用剛剛的.js檔 -->
        <script src="JS/jquery.autoheight.js"></script> 
     
        <!-- inline scripts related to this page -->
        <script type="text/javascript"> 
            $(function () {   
                //↓其實<a>也可以設定target屬性為iframe的name, 就可以把點擊的超連結開在iframe,見文章底下的W3Schools說明範例
                $("a").click(function (evt) {
                    evt.preventDefault();//避免導頁
                     let href = $(this).attr("href"); 
                     if (href === "#") {
                        return;//不往下執行
                    }
                    //do something....
                        
                    //iframe導頁
                    $("iframe:first").attr("src", href); 
                });
                
            }); 
        </script>

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

iframe換頁的另一辦法↓

結語

以上須留意,由於程式主要針對iframe的load事件才改變iframe高度

所以若iframe內容是MVVM、SPA網頁或iframe內嵌網頁有發出Ajax並改變DOM內容的話,上述程式碼可能無法自動高度。