Faire communiquer des iframes
postMessage est une des méthodes permettant à une page d'échanger des données avec une iframe ou à des iframes de communiquer entre elles.
Utiliser le DOM
Mais ce n'est pas la plus simple. Une iframe peut accèder au contenu de la page qui la contient avec la propriété parent de window. Et inversement la page accède à l'iframe par son identifieur et à l'objet window, suivant le navigateur par la propriété contentWindows ou contentDocument.
<iframe id="if1" src="iframe-demo.html"></iframe> var if = document.getElementById("if1");
var fc = (if1.contentWindow || if1.contentDocument);
Ci-dessous, la page iframe-demo.html qui l'on inclut dans une iframe sur cette page...
Elle contient un texte et une image.
On peut en passant par le DOM remplacer cette image par une autre...
Code source:
<script>
function replaceImg(img) {
var if1 = document.getElementById("if1");
var fc = (if1.contentWindow || if1.contentDocument);
var img1 = fc.document.getElementById("idemo");
img1.src=img;
}
</script>
<p><input type="button" value="Remplacer" onclick="replaceImg('images/angry-birds.jpg')" /></p>
Source code dans iframe-demo.html
<img id="idemo" src="/html5/images/freeciv.jpg">
iFrame et document parent
La page insérée dans l'iframe peut communiquer également par le DOM. Cliquez sur le bouton dans l'iframe pour envoyer les données sur cette page.
Code source dans cette page:
<iframe id="if2" src="iframe-demo2.html" width="320" height="150"></iframe>
<fieldset><legend>Champ à remplir</legend><div id="storage"></div></fieldset>
Code source dans iframe-demo2.html:
<script>
function sendDataToContainer() {
var storage = parent.document.getElementById("storage");
var data = document.getElementById("data");
storage.innerHTML = data.innerHTML;
}
</script>
<p id="data">Texte transféré...</p>
<p><input type="button" value="Remplacer" onclick="sendDataToContainer()" /></p>
postMessage
Une API standard a été définie par le W3C pour faire communiquer des pages web indépendantes. Elle ajoute la méthode postPaster à l'objet Windows pour envoyer des données, et l'évènement "message" pour les réceptionner. Notez que postMaster n'est pas associé à l'objet window de la page qui l'appelle, mais à celui de la page qui reçoit les données.
Il est nécessaire de spécifier le domaine comme argument de la méthode. Xul.fr est utilisé dans l'exemple pour qu'il fonctionne sur ce site. Dans votre application, vous utiliserez votre domaine.
On affiche à titre de démonstration dans deux iframes les pages iframe-demo3.html et iframe-demo4.html. On veut pouvoir échanger des données (un simple texte dans la démonstration) entre la page principales et celles des iframes.
Cliquez sur le bouton dans une iframe pour transférer le texte qu'elle contient, vers cette page.
Code source sur la page principale (sans le code de présentation):
<iframe id="if3" src="iframe-demo3.html" width="320" height="200"></iframe>
<iframe id="if4" src="iframe-demo4.html" width="320" height="200"></iframe>
<div id="storage3"></div>
<script>
function getMessage(e) {
if(e.origin !== 'https://www.xul.fr') return;
document.getElementById("storage3").innerHTML=e.data;
}
window.addEventListener("message", getMessage, false);
function sendMessage(id) {
var data = document.getElementById("data").innerHTML;
var ifr = document.getElementById(id);
var target = (ifr.contentWindow || ifr.contentDocument);
target.postMessage(data, 'https://www.xul.fr');
}
</script>
<p id="data">Texte à envoyer vers l'iframe.</p>
<input type="button" value="Transférer à gauche" onClick="sendMessage('if3')" />
<input type="button" value="Transférer à droite" onClick="sendMessage('if4')" />
Remplacez https://www.xul.fr par votre domaine.
Code source dans la page chargée dans l'iframe:
<script>
<script>
function getMessage(e) {
if(e.origin !== 'https://www.xul.fr') return;
document.getElementById("storage").innerHTML=e.data;
}
window.addEventListener("message", getMessage, false);
function sendMessage() {
var data = document.getElementById("data").innerHTML;
window.parent.postMessage(data, 'https://www.xul.fr');
}
</script>
<p id="data">Données de iframe-demo3.html...</p>
<div id="storage"></div>
<input type="button" value="Transférer" onClick="sendMessage()" />
Communiquer directement entre les iframes est aussi possible en combinant window.parent avec target comme défini ci-dessus.
En conclusion, la méthode postMessage est une alternative plus dynamique au DOM seul, convenant mieux si l'on charge de multiples pages dans une même iframe, mais pas plus simple et cela requiert toujours l'emploi du DOM.
WebMessaging fait maintenant partie de la spécification HTML 5.