function resizeCrossDomainIframe(id, other_domain) {
var iframe = document.getElementById(id);
window.addEventListener('message', function (event) {
if (event.origin !== other_domain) return; // only accept messages from the specified domain
if (event.data === "reload") top.location.reload(); // If child page sends reload request - reload it without any questions asked
if (isNaN(event.data)) { //If this isn't integer than it is alert
alert(event.data); // Show alert if not integer
} else {
var height = parseInt(event.data) + 5; // add some extra height to avoid scrollbar
iframe.height = height + "px";
alert(event.data);
}
}, false);
}
what it does is dynamically resizes iframe. Now On a first iframe page I just get one alert, but in within iframe page i have links and when I go to second page I see 2 alerts, when I go to third page - i get 3 alerts, 4th link trigger 4 alerts etc...
In each iframed page I am calling parent to resize like:
I tried to clear the "event" array, but I still get Alerts, but this time they are empty, but the number of alerts equals the number of link-clicks within the iframe ?
Why is this and how to limit it only to one "alert"?
My guess is, that you have multiple eventListeners for the same event. Do you call that function more than once? On every click? Maybe you could extract the necessary code including HTML and post it here, so we can test our solutions...
<script>
function resizeCrossDomainIframe(id, other_domain) {
var iframe = document.getElementById(id);
window.addEventListener('message', function (event) {
if (event.origin !== other_domain) return; // only accept messages from the specified domain
if (event.data === "reload") top.location.reload(); // If child page sends reload request - reload it without any questions asked
if (isNaN(event.data)) { //If this isn't integer than it is alert
alert(event.data); // Show alert if not integer
} else {
var height = parseInt(event.data) + 5; // add some extra height to avoid scrollbar
iframe.height = height + "px";
alert(event.data); // Show alert even if it is integer, just to see that alerts are fired multiple times...
}
}, false);
}
</script>
<div style="width: 984px; margin: 0px auto;">
<iframe id="mysample_iframe_id" name="mysample_iframe" src="http://www.IframeDestinationLocation.com/index.php" style="width:982px; onload="resizeCrossDomainIframe('mysample_iframe_id', 'http://IframeDestinationLocation.com');\"></iframe>
</div>
That's about the main page - it setups iframe and listener to pickup response, and now within iframe is actual site (with it's own links). Now in each page I am calling it like:
Now all those pages (link1.html, link2.html etc..) they have same onload callback (as I obviously want to adjust height for each page as not all the pages are same height)
So on first page all looks right, but when user progress by clicking links within Iframe e.g. clicks on Link2 - Alert will popup TWICE, now if he clicks on Link3 - alert will show three times, fourth link click will fire four alerts etc...
Now my question is how to make it fire only one alert ? ...or why it is triggering multiple alerts when it is supposed to trigger only once when body onload happens ?
e.g. clicks on Link2 - Alert will popup TWICE, now if he clicks on Link3 - alert will show three times, fourth link click will fire four alerts etc...
It's not really dependent on which link the user clicks, but on the number of links visited since the main page load, right? Because that's how you described it...
Well, it seems, that i was right. You call resizeCrossDomainIframe() on every iframe load, which also adds another listener. Try moving that onload from iframe to body of the main page.
Now I modified a code in "main page" to something like this:
Code:
if (isNaN(event.data)) {
var IframeResponse = event.data;
alert(IframeResponse.ifrtype);
if (event.data.ifraction == "ALERT" && event.data.ifrtype == "SUCCESS" ) {
alert(event.data.ifrmessage);
}
if (event.data.ifraction == "ALERT" && event.data.ifrtype == "ERROR" ) {
alert(event.data.ifrmessage);
}
}
Now it works IN ALL browsers, except IE9 (I've tested in FFox, Chrome, Safari, Opera)
IE alerts "Undefined" for this ??? Is there a way to make it work in IE9 at least...
Well, i am not 100% sure, but i believe it's because IE needs the message data to be of type string. As mentioned in this article, even earlier versions of FF required it. To be most cross-browser compatible, you should only use strings. If you always specify action, type and message, you can delimit them with some special character (|,#,@,...) or even string and then use
Code:
//if you use the vertical pipe character and send
//parent.postMessage("ALERT|ERROR|Sample message"}, 'http://MainSiteLocation.com');
dataArray = data.split( "|" );
action = dataArray[0]; //"ALERT"
type = dataArray[1]; //"ERROR"
message = dataArray[2]; //"Sample message"
when sending, send JSON.stringify(oldValueToSend), and when handling messages, say e.data=JSON.parse(e.data), which ensures you have objects going in and coming out to your orig code.
Bookmarks