One effective approach I propose is to assign a unique identifier to each iframe randomly. During any communication between the iframe and its parent window, the iframe should include its individual identifier in the content of a postMessage. This method enables the parent window to quickly and easily identify the source of incoming messages.
Below is an updated example where the contents of hello-iframe.html are:
<html>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script>
var exec = function() {
var message = "Hello world, this is a test of the emergency broadcast system.";
var index;
document.body.appendChild(document.createElement("hr"));
for (index = 0; index < message.length; index++) {
createCharacterIframe(message.charAt(index));
}
document.body.appendChild(document.createElement("hr"));
};
var _gensymCounter = 0;
var gensym = function() {
var output = [], index;
var LENGTH = 32;
output.push((_gensymCounter++) + "_");
var characters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
for (index = 0; index < LENGTH; index++) {
output.push(characters.charAt(Math.floor(Math.random() * characters.length)));
}
return output.join('');
};
var createCharacterIframe = function(ch, id) {
id = id || gensym();
var newIframe = document.createElement("iframe");
newIframe.setAttribute("frameborder", "0");
newIframe.setAttribute("border", "0px");
newIframe.setAttribute("width", "0px");
newIframe.setAttribute("height", "0px");
newIframe.setAttribute("src", "hello-iframe-inner.html?selfId=" + encodeURIComponent(id));
newIframe.setAttribute("id", id);
$(newIframe).data('ch', ch);
document.body.appendChild(newIframe);
};
var locateIframe = function(w) {
var located;
$('iframe').each(function() {
if (this.contentWindow == w) {
located = this;
}
});
return located;
};
$(window).on('message',
function(e) {
var data = e.originalEvent.data;
var source = e.originalEvent.source;
var iframe, sourceId;
if(data.match(/^([^,]+)[,](.+)$/)) {
sourceId = RegExp.$1;
data = RegExp.$2;
if (document.getElementById(sourceId)) {
iframe = document.getElementById(sourceId);
} else {
return;
}
} else {
return;
}
if (data === 'ready') {
iframe.contentWindow.postMessage($(iframe).data('ch'), '*');
} else if (data.match(/^(\d+),(\d+)$/)) {
var w = RegExp.$1;
var h = RegExp.$2;
if (iframe.width !== w + 'px') {
iframe.width = w + "px";
}
if (iframe.height !== h + 'px') {
iframe.height = h + "px";
}
}
});
$(document).ready(exec);
</script>
<body>
<h1>testing iframes</h1>
</body>
</html>
and the content of hello-iframe-inner.html as follows:
<html><head></head>
<script>
// http://stackoverflow.com/questions/901115/get-query-string-values-in-javascript
var urlParams = {};
(function () {
var e,
a = /\+/g,
r = /([^&=]+)=?([^&]*)/g,
d = function (s) { return decodeURIComponent(s.replace(a, " ")); },
q = window.location.search.substring(1);
while (e = r.exec(q))
urlParams[d(e[1])] = d(e[2]);
})();
var SELF_ID = urlParams.selfId;
window.addEventListener("message",
function(e) {
if (e.data === ' ') {
document.body.innerHTML = " ";
} else {
document.body.appendChild(
document.createTextNode(e.data));
}
});
window.onload = function() {
document.body.style.margin = '0px';
var width, height;
if (window.parent && SELF_ID) {
window.parent.postMessage(SELF_ID + ',ready', '*');
setInterval(function() {
if (height !== document.body.scrollHeight ||
width !== document.body.scrollWidth) {
width = document.body.scrollWidth;
height = document.body.scrollHeight;
if (window.parent) {
window.parent.postMessage(SELF_ID + ',' + width + ',' + height, '*');
}
}
}, 1000);
}
};
</script>
<body></body>
</html>