Archive

Archive for March, 2011

Dynamic Sizing of a cross domain iframe

March 25th, 2011 No comments

There are several ways to communicate via domains in a browser. One of the simplest is using the hash on a url… i.e. The part of the url AFTER the # sign.

The way this works is… The parent window can set the url of the child iframe, and the child iframe can set the url of the parent window. The only hangup, is that both windows need to know the correct location for the other window before they can properly set the hash on the other’s url without navigating the other to a different url…

Recently I explored methods of accomplishing this for a project I was working on. After trying a few solutions I came up with a simple clean solution that works GREAT if both sides already know the url for the other… And acutally, for resizing, only the page in the iframe needs to know the right url for the parent, as the communication is only one way… Below is the code… (jQuery is required, but this could easily be changed just by setting the function as an event handler without jQuery.)

So… On all pages in the child iframe you want to resize make sure jQuery is installed and add this code…

jQuery(document).ready(
	function(){
		iframe_resize_extend_jQuery();
		if (top != self) {
			var parent_url = jQuery.getUrlVar('parent_url');
			if(parent_url){
				parent_url = unescape(parent_url);
				jQuery.cookie('parent_url', parent_url);
			} else {
				parent_url = jQuery.cookie('parent_url');
			}
			
			if(parent_url){
				var url = parent_url + '#'  + document.body.scrollWidth + 'x' + document.body.scrollHeight;			
				parent.location = url;
			}
		}		
	}
);


function iframe_resize_extend_jQuery(){
	if(!jQuery.cookie) jQuery.cookie = function(name, value, options) {
		if (typeof value != 'undefined') { // name and value given, set cookie
			options = options || {};
			if (value === null) {
				value = '';
				options.expires = -1;
			}
			var expires = '';
			if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
				var date;
				if (typeof options.expires == 'number') {
					date = new Date();
					date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
				} else {
					date = options.expires;
				}
				expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
			}
			// CAUTION: Needed to parenthesize options.path and options.domain
			// in the following expressions, otherwise they evaluate to undefined
			// in the packed version for some reason...
			var path = options.path ? '; path=' + (options.path) : '';
			var domain = options.domain ? '; domain=' + (options.domain) : '';
			var secure = options.secure ? '; secure' : '';
			document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
		} else { // only name given, get cookie
			var cookieValue = null;
			if (document.cookie && document.cookie != '') {
				var cookies = document.cookie.split(';');
				for (var i = 0; i < cookies.length; i++) {
					var cookie = jQuery.trim(cookies[i]);
					// Does this cookie string begin with the name we want?
					if (cookie.substring(0, name.length + 1) == (name + '=')) {
						cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
						break;
					}
				}
			}
			return cookieValue;
		}
	};

	if(!jQuery.getUrlVars) jQuery.getUrlVars = function(){
		var vars = [], hash;
		var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
		for(var i = 0; i < hashes.length; i++)
		{
		  hash = hashes[i].split('=');
		  vars.push(hash[0]);
		  vars[hash[0]] = hash[1];
		}
		return vars;
	};

	if(!jQuery.getUrlVar) jQuery.getUrlVar = function(name){
		return jQuery.getUrlVars()[name];  
	};
}

And, on the parent window add...



var refreshFrequency = 30;
var extraHeight = 0;
var extraWidth = 0;
var lastHeight = 0;
var lastWidth = 0;
var iframeId = 'resizeIframe';

function checkIFrameSize(){
  if(window.location.hash && document.getElementById(iframeId)){
    var currentHeight = parseInt(document.getElementById(iframeId).style.height.replace(/[^0-9]/g, ''));

    var dimensions = window.location.hash.split('x');

    if(dimensions.length == 2){
        var width = parseInt(dimensions[0].replace(/[^0-9]/g, ''));
        var height = parseInt(dimensions[1].replace(/[^0-9]/g, ''));
    }
    if(!isNaN(width) && !isNaN(height)){
        var newWidth = (width + extraWidth);
        if(lastWidth != newWidth){
            document.getElementById(iframeId).style.width =  (newWidth) + 'px';
            lastWidth = newWidth;
        }

        var newHeight = (height + extraHeight);
        if(newHeight != lastHeight){
            document.getElementById(iframeId).style.height = (newHeight) + 'px';
            lastHeight = newHeight;
        }
    }
  }
  setTimeout(checkIFrameSize, refreshFrequency);
}

setTimeout(checkIFrameSize, refreshFrequency);

That's it!

Categories: html, Uncategorized Tags: