Page and Iframe communication with postMessages

17 בNovember 2013

one comment

  I was interviewed in a company that deals with advertizing. They asked me a question I didn’t get right, seeking for a way
to determine whether a commercial, located in an <iframe>, is on the
visible screen or not. So, what do you do after you don’t get the right answer to the question?
Go and find it. So I did. In HTML5, on of its API is a method named postMessage. This method
enables window objects (such as iframes) to communicate with one another. With this API the solution is quite simple: When loaded ,the hosted frame can send a request for
the hosting page for its frame position, The hosting page will calculate whether the frame is within
the visible screen and send its answer back

Hosted frame code:

if (!window.addEventListener) {

         window.attachEvent("DOMContentLoaded", function () {

             window.parent.postMessage("I am loaded", getOriginAddress());

         }

         );

         window.attachEvent("message", function (message) {

             handleMessage(message);

 

         });

     }

     else {

         window.addEventListener("DOMContentLoaded", function () {

             window.parent.postMessage("I am loaded", getOriginAddress());

         });

         window.addEventListener("message", function (message) {

             handleMessage(message);

           

         });

     }

 

     var handleMessage = function (message) {

         console.log(message);

         document.getElementById("positionData").innerText =

             "top " + message.data.top + ", left " + message.data.left

         + (message.data.inscreen ? " In Screen" : " Out of screen");

     };

     var getOriginAddress = function()

     {

         return window.location.protocol + "//" + window.location.host + ":"

             + window.location.port;

     }

 

Hosting page code

if (!window.addEventListener) {

            window.attachEvent("message", function (message) {

                sendLocationMessage(message);

 

            });

        }

        else {

            window.addEventListener("message", function (message) {

                sendLocationMessage(message);

 

            });

        }

 

        var sendLocationMessage = function (message) {

            console.log(message);

            var element = message.source.frameElement;

            message.source.postMessage({

                top: element.offsetTop, left: element.offsetLeft, inscreen:

                    element.offsetTop < screen.availHeight && element.offsetLeft < screen.availWidth

            }, message.origin);

        };

Few notes:

1. In this code, the iframe element ID is sent by query-string to the hosted page,  using frameElement won’t work when the hosting page and the iframe source are from different domain
2. For cross domain testing, you may change the iframe sources
3. It could work if the two are on the same domain but different sub-domain, after you set the document.domain
    to be the root domain (example:  ‘about.postmessages.com’ and  ‘demo.postmessages.com’ can work if you change the document.domain
    to ‘postmessages.com’)
4. For browser support you can refer to http://caniuse.com/#feat=x-doc-messaging 

Summary:

postMessage is an efficient way to have cross document messaging and something a pity I didn’t remember
while being interviewed.
 
You can download the full demo here

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

one comment

  1. Selected28 בDecember 2016 ב 15:31

    Thank you for the info, it really helped!

    Reply