EladElrom.com

Deep Dive Into Technology

Update HTML document layout (width & height) using Javascript after browser resize

To adjust the page’s layout you need to listen to change in browser size event. You can do that in jQuery easily and the method in jQuery already taking care of a lot of the logic needed, however if you want to just use Javascript you can. JS has everything you need to get it working.

var oldWidth;
var oldHeight

function resizeHandler()
{
	var newWidth;
	var newHeight;

	if( typeof( window.innerWidth ) == 'number' )  //Non-IE
	{
		newWidth = window.innerWidth;
		newHeight = window.innerHeight;
	}
	else if( document.documentElement &&
	( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) //IE 6+
	{
		newWidth = document.documentElement.clientWidth;
		newHeight = document.documentElement.clientHeight;
	}
	else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) )  // IE4
	{
		newWidth = document.body.clientWidth;
		newHeight = document.body.clientHeight;
	}

	if ( newWidth != oldWidth )
	{
               // implement -- do something

		oldWidth = newWidth;
		oldHeight = oldHeight;
	}
}

Notice that I am checking if the actual size was changed since often the browser will call this method several times as the user resize it’s browser. Also notice that this code is set to take into account different types of browsers.

Than you can set the body to call this method onload

<body onload='parent.resizeHandler()'>

I also noticed that sometimes the event is called before the page completed the layout process so I added a timer:

function callChatAfterOnLoadCompleted()
{
	var t2=setTimeout("parent.resizeHandler()", 500);
}

And on window resize:

window.onresize = function(event)
{
	parent.resizeHandler()
}

Getting information about a page in an iframe that lives on a separate domain

Recently I created an iframe and the page inside of the iframe was redirecting to another page on a different domain. One would think that this is a simple task (just as you can do if they both lives on the same domain) and you can just pull the new URL out of the page using ajax once a change was made in the page or use the pseudo code standard as explained on wikipedia: http://en.wikipedia.org/wiki/XMLHttpRequest.

However these techniques didn’t work since there are cross domain restrictions. The browsers wont allow your parent page to access a different domain’s information since it can be abused by hackers.

HTML5 added the option to use the “postMessage” method and call the parent document. That will allow other domains to access the iframe page, so you would need permission from the parent domain and they can call a method in the parent domain that will let your parent document know that there have been change in the iframe,

For instance, a web master can create a wrapper for his page and place it in a wrapper and than use HTML5 new method “postMessage” to call the parent page and restrict it to a domain or just leave it as a wild card “*”

<?php
	$iframeStartURL = "http://[someURL]";

?>
<html>
<head>
	<title>Wrapper</title>
</head>
<body>

    <form id="frm1" name="frm1">
    	<input type="text" id="txtURL" value="<?php echo $iframeStartURL; ?>" style="visibility:hidden" />
    </form>

    <script type="text/javascript">
        var myURL = document.getElementById("txtURL");
        function GetSRC() {
			try {
				ajax.receive();
			}catch (err){
				alert("Error : " + err );
			}
        }

        var ajax =
        {
            send: function (urlstring) {
                if (!this.ifram) {
                    this.ifram = document.createElement('iframe');
                    this.ifram.style.display = 'none';
                    if (this.ifram.addEventListener) this.ifram.addEventListener('load', ajax.receive, false);
                    else if (this.ifram.attachEvent) this.ifram.attachEvent('onload', ajax.receive);
                    document.body.appendChild(this.ifram);
                }
                this.ifram.setAttribute('src', urlstring);
            },
            receive: function () {
				var newURL = ajax.ifram.getAttribute("src");
				if (newURL != null)
				{
					// send the new URL to parent window
					parent.postMessage(ajax.ifram.contentWindow.location.href, "http://[domain you allow]");
				}

                return;
            }
        };

		ajax.send(myURL.value);

    </script>
</body>
</html>

the parent window will be able to receive the message:

<html>
<head>
	<title></title>
</head>
<body>
    <iframe src="http://[some domain]"
        width="0%" height="0%" style="visibility:hidden">
    </iframe>

    <script>
		window.onload = function()
		{
			window.addEventListener( "message", function (evt) {

				if (evt.origin !== "http://eladelrom.com/blog/") {
					alert("cross domain issue");
				}

				alert(evt.data);
			}, false);
		};
	</script>
</body>
</html>

Other option is to use the “Access-Control-Allow-Origin” to the domain that you are trying to access to allow the parent document from a different domain to access the page.

However, sometimes you are using a page for your iframe that you don’t own or have access to and wont have the ability to use the HTML 5 method, plus the HTML 5 method wont work on all browsers so legacy browsers will suffer.

What you can do is create a server side script that will go and fetch a domain recognize the redirect or change in the page and send the result back to your parent page. For instance, here is how it can be done in PHP:

	$ch = curl_init("http://[domain]/[url]");

	curl_setopt($ch, CURLOPT_FOLLOWLOCATION, FALSE);
	curl_setopt($ch, CURLOPT_HEADER, TRUE);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);

	$result = curl_exec($ch);
	$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
	curl_close($ch);

	if($code == 307) {
	  // Get the url from the location header
	  $regexp="/Location: (.*)$/m";
	  preg_match($regexp, $result, $matches);
	  $match1 = $matches[1];
	}