Cross Domain Iframe Resize

Recently I was trying to set an iframe height which is hosted in another domain. But could not able to get its height from its hosting window - It always throws security exception. I searched Google and found a interesting example on Iframe cross domain messaging, here is the link. Based upon it I have created a small solution which finally does the job. Here are files, you can also download these files from this link:

// FrameManager.js -- Must be added in Hosting window
var FrameManager =
{
currentFrameId : '',
currentFrameHeight : 0,
lastFrameId : '',
lastFrameHeight : 0,
resizeTimerId : null,

init : function()  
{  
    if (FrameManager.resizeTimerId == null)  
    {  
        FrameManager.resizeTimerId = window.setInterval(FrameManager.resizeFrames, 500);  
    }  
},  

resizeFrames : function()  
{  
    FrameManager.retrieveFrameIdAndHeight();  

    if ((FrameManager.currentFrameId != FrameManager.lastFrameId) ||  
        (FrameManager.currentFrameHeight != FrameManager.lastFrameHeight))  
    {  
        var iframe = document.getElementById(FrameManager.currentFrameId.toString());  

        if (iframe == null) return;  

        iframe.style.height = FrameManager.currentFrameHeight.toString() + "px";  

        FrameManager.lastFrameId = FrameManager.currentFrameId;  
        FrameManager.lastFrameHeight = FrameManager.currentFrameHeight;  
        window.location.hash = '';  
    }  
},  

retrieveFrameIdAndHeight : function()  
{  
    if (window.location.hash.length == 0) return;  

    var hashValue = window.location.hash.substring(1);  

    if ((hashValue == null) || (hashValue.length == 0)) return;  

    var pairs = hashValue.split('&');  

    if ((pairs != null) && (pairs.length > 0))  
    {  
        for(var i = 0; i < pairs.length; i++)  
        {  
            var pair = pairs\[i\].split('=');  

            if ((pair != null) && (pair.length > 0))  
            {  
                if (pair\[0\] == 'frameId')  
                {  
                    if ((pair\[1\] != null) && (pair\[1\].length > 0))  
                    {  
                        FrameManager.currentFrameId = pair\[1\];  
                    }  
                }  
                else if (pair\[0\] == 'height')  
                {  
                    var height = parseInt(pair\[1\]);  

                    if (!isNaN(height))  
                    {  
                        FrameManager.currentFrameHeight = height;  
                        FrameManager.currentFrameHeight += 15;  
                    }  
                }  
            }  
        }  
    }  
},  

registerFrame : function(frame)  
{  
    var currentLocation = location.href;  
    var hashIndex = currentLocation.indexOf('#');  

    if (hashIndex > -1)  
    {  
        currentLocation = currentLocation.substring(0, hashIndex);  
    }  

    frame.contentWindow.location = frame.src + '?frameId=' + frame.id + '#' + currentLocation;  
}  

};

window.setTimeout(FrameManager.init, 300);

IFrame Resize Sample
var frameId = getFrameId();  

if (frameId == '') return;  

var actualHeight = getBodyHeight();  
var currentHeight = getViewPortHeight();  

if  (Math.abs(actualHeight - currentHeight) > 15)  
{  
    var hostUrl = window.location.hash.substring(1);  

    hostUrl += "#";  
    hostUrl += 'frameId=' + frameId;  
    hostUrl += '&';  
    hostUrl += 'height=' + actualHeight.toString();  

    window.top.location = hostUrl;  
}  

}

function getFrameId()
{
var qs = parseQueryString(window.location.href);
var frameId = qs["frameId"];

var hashIndex = frameId.indexOf('#');  

if (hashIndex > -1)  
{  
    frameId = frameId.substring(0, hashIndex);  
}  

return frameId;  

}

function getBodyHeight()
{
var height;
var scrollHeight;
var offsetHeight;

if (document.height)  
{  
    height = document.height;  
}  
else if (document.body)  
{  
    if (document.body.scrollHeight)  
    {  
        height = scrollHeight = document.body.scrollHeight;  
    }  
    if (document.body.offsetHeight)  
    {  
        height = offsetHeight = document.body.offsetHeight;  
    }  

    if (scrollHeight && offsetHeight)  
    {  
        height = Math.max(scrollHeight, offsetHeight);  
    }  
}  

return height;  

}

function getViewPortHeight()
{
var height = 0;

if (window.innerHeight)  
{  
    height = window.innerHeight - 18;  
}  
else if ((document.documentElement) && (document.documentElement.clientHeight))  
{  
    height = document.documentElement.clientHeight;  
}  
else if ((document.body) && (document.body.clientHeight))  
{  
    height = document.body.clientHeight;  
}  

return height;  

}

function parseQueryString(url)
{
url = new String(url);
var queryStringValues = new Object();
var querystring = url.substring((url.indexOf('?') + 1), url.length);
var querystringSplit = querystring.split('&');

for (i = 0; i < querystringSplit.length; i++)  
{  
    var pair = querystringSplit\[i\].split('=');  
    var name = pair\[0\];  
    var value = pair\[1\];  

    queryStringValues\[name\] = value;  
}  

return queryStringValues;  

}

Page In IFrame
This article is part of the GWB Archives. Original Author: Kazi Manzur Rashid

New on Geeks with Blogs