IE8下IFrame 和子頁面的通訊

業務中遇到這種場景,咱們的業務嵌入別的系統中使用,系統採用Iframe調用咱們的業務,在使用過程當中主要遇到兩個問題:javascript

1。子頁面高度發生變化時外部的Iframe高度自適應的問題。html

2。子頁面不一樣獲取外部scrollTop的問題。java

這兩個問題其實均可以說是跨域通訊的問題。跨域

這兩個問題咱們採用了不一樣不一樣的方案來解決。瀏覽器

1。子頁面高度發生變化時外部的Iframe高度自適應的問題。post

咱們採用在外部系統中增長一個代理頁面,這樣的話這個代理頁面就和外部系統處於同一個域中了,至關於咱們在外部系統中安插了一個內鬼,使用這個代理頁面來調整外部Iframe的高度。ui

代碼實現spa

window.setInterval("proxyHeight()", 400);//每隔400毫秒監聽下頁面高度(其實就是咱們子頁面的高度)
var pageHeightPre = 0;
function proxyHeight() {
    var proxyUrl = Rose.browser.getParameter('proxyUrl');//獲取代理頁面的URL
    if (proxyUrl != null){
        
        var height = document.documentElement.scrollHeight;
        if(Rose.browser.ie){
            height = document.body.scrollHeight;
        }
        if(height <= 0) {
            return;
        }
        if (height < 450) {
            height = 450;
        }

        if(height != 0 && pageHeightPre != height){
            pageHeightPre = height;
            document.getElementById('proxyFarme').src= proxyUrl +'?proxyHeight='+height;
        }
    }
}

 

代理頁面的代碼大體是這樣的代理

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="./js/common/Rose/1.0.0/Rose.src.js"></script>
</head>
<body>
</body>
</html>
<script type="text/javascript" >
window.onload = function(){
    var proxyHeight = Rose.browser.getParameter('proxyHeight');
    if(proxyHeight != null){
        parent.parent.reinitIframe(proxyHeight);//調用系統的reinitIframe方法
} } </script>

reinitIframe方法的邏輯較簡單code

function reinitIframe(height) {
        var iframe = $(".ui-navtab-iframe:visible").find("iframe");
        $(iframe).height(height);
    }

這種方式也能知足咱們業務須要。

2。子頁面不一樣獲取外部scrollTop的問題,這個問題咱們採用postMessage的方式。

在外部系統中咱們監聽滾動條的事件

$(window).scroll(function(event){
    var iframe = $(".ui-navtab-iframe:visible").find("iframe");
    if(iframe.length == 0){ 
        return;
    }
        var scrollHeight = $(document).scrollTop()
        scrollHeight = JSON.stringify({'scrollHeight': scrollHeight});
        iframe[0].contentWindow.postMessage(scrollHeight, "*");

    });

在子業務中接受消息

function receiveMessage(e){
    if (e != null && e != undefined && e.data != undefined ){
        if(typeof(e.data) == "string"){
            try{
                var data = JSON.parse(e.data);
                if(data.scrollHeight != null && data.scrollHeight != undefined){
                    window.iframScrollHeight = data.scrollHeight;
                }
            }catch(e){
            }
        }
    }
}
attachEventListener("message",receiveMessage);
function attachEventListener(type, listener){
    if(window.addEventListener){ // 兼容全部瀏覽器除了ie9如下
        window.addEventListener(type, listener, false);
    }else if(window.attachEvent){ // 兼容ie9如下瀏覽器
        window.attachEvent("on"+type, listener);
    }
}

這樣的話只要外部的滾動條有變化就會發送滾動條目前高度的消息,子頁面接收到消息後 就能獲取到外部的滾動條的高度了,也能知足業務須要。

美中不足的是目前的寫法是實時監聽,不過也能夠修改成子頁面發送消息給外部Iframe ,使之獲取滾動條的高度後在發消息給子頁面。各有優劣吧。

相關文章
相關標籤/搜索