This question has been asked a lot, and the answers are usually similar.
In basic terms, I need a function to perform when the contents of an iframe are clicked.
For the purposes of this demonstration, I have http://mydomain.com/iframe.html which contains an iframe with an ID of "iframeID" and a source of http://mydomain.com.
This code works:
jQuery(document).ready(function(){
$('#iframeID').contents().click(function(event) {
console.log('Clicked! ' + event.pageX + ' - ' + event.pageY);
});
});
But, this code only works in Internet Explorer. I need a solution that will work in all browsers.
The good news is, this is all on the same domain so if I need to put additional code in either the iframe source or my iframe.html then that's fine. I just need it to work cross-browser.
One other point to note, is I have a desire for this to work across subdomains.
I know it won't work with different domains, but as I understand it, subdomains should be fine? Any extra steps required for that to work?
Any help gratefully received!
Here is an example I've put together on jsFiddle that demonstrates one way to use XDM:
This is the demo and it includes this fiddle as a child iframe
HTML (parent):
<h1>Parent window</h1>
<input id="message-for-child" type="text" value="" placeholder="(message for child)">
<button id="parent-to-child-button">Send to child</button>
<br>
<p id="parent-message"></p>
<br>
<iframe id="child" src="http://fiddle.jshell.net/quant/G2uq6/show/"></iframe>
JavaScript (parent):
// parent_on_message(e) will handle the reception of postMessages (a.k.a. cross-document messaging or XDM).
function parent_on_message(e) {
console.log("parent_on_message event fired: ", e);
// You really should check origin for security reasons
// https://developer.mozilla.org/en-US/docs/DOM/window.postMessage#Security_concerns
if (e.origin.search(/^http[s]?:\/\/.*\.jshell\.net/) != -1
&& !($.browser.msie && $.browser.version <= 7)) {
var returned_pair = e.data.split('=');
if (returned_pair.length != 2)
return;
if (returned_pair[0] === 'message-for-parent') {
$("p#parent-message").html(returned_pair[1]);
}
else
console.log("Parent received invalid message");
}
}
jQuery(document).ready(function($) {
// Setup XDM listener (except for IE < 8)
if (!($.browser.msie && $.browser.version <= 7)) {
// Connect the parent_on_message(e) handler function to the receive postMessage event
if (window.addEventListener)
window.addEventListener("message", parent_on_message, false);
else
window.attachEvent("onmessage", parent_on_message);
}
$("button#parent-to-child-button").on("click", function(e) {
console.log("Sending: " + $("input#message-for-child").attr("value"));
$("iframe#child").get(0).contentWindow.postMessage('message-for-child=' + $("input#message-for-child").attr("value"), '*');
});
});
HTML (child):
<h1>Child</h1>
<input id="message-for-parent" type="text" value="" placeholder="(message for parent)">
<button id="child-to-parent-button">Send to parent</button>
<br>
<p id="child-message"></p>
JavaScript (child):
// child_on_message(e) will handle the reception of postMessages (a.k.a. cross-document messaging or XDM).
function child_on_message(e) {
console.log("child_on_message event fired: ", e);
// You really should check origin for security reasons
// https://developer.mozilla.org/en-US/docs/DOM/window.postMessage#Security_concerns
if (e.origin.search(/^http[s]?:\/\/.*\.jshell\.net/) != -1
&& !($.browser.msie && $.browser.version <= 7)) {
var returned_pair = e.data.split('=');
if (returned_pair.length != 2)
return;
if (returned_pair[0] === 'message-for-child') {
$("p#child-message").html(returned_pair[1]);
}
else
console.log("Child received invalid message");
}
}
jQuery(document).ready(function($) {
// Setup XDM listener (except for IE < 8)
if (!($.browser.msie && $.browser.version <= 7)) {
// Connect the child_on_message (e) handler function to the receive postMessage event
if (window.addEventListener)
window.addEventListener("message", child_on_message , false);
else
window.attachEvent("onmessage", child_on_message );
}
$("button#child-to-parent-button").on("click", function(e) {
console.log("Sending: " + $("input#message-for-parent").attr("value"));
parent.window.postMessage('message-for-parent=' + $("input#message-for-parent").attr("value"), '*');
});
});
Further reading:
- XDM tutorial
- XDM info
- XDM security #1
- XDM security #2
If you just want to make links in the iframe open in the top window instead of inside of the iframe check out How to force link from iframe to be opened in the parent window
Just put this in the head of the iframe HTML:
<base target="_parent" />