Les frames sont de plus en plus rejetées par le monde de l'internet. La plupart des grands sites les ont abandonnées et ont choisi de recopier sur chaque page le menu et tous les liens de leur navigation. Nous allons tout de même aborder la mise en place des frames et surtout leur intérêt dans la programmation JavaScript.
Pour créer une page séparée en plusieurs frames, il faut à l'origine une page principale qui remplace la zone BODY par la déclaration et le positionnement des frames.
La structure classique d'une page découpée en frames est celle-ci.
<html> <head> <title>Titre de page contenant les frames</title> </head> <frameset cols="140,*"> <frameset rows="*,50" frameborder=0> <frame name="frame1" src="frame1.html"> <frame name="frame2" src="frame2.html"> </frameset> <frame name="frame3" src="frame3.html"> </frameset>Cette déclaration crée une page découpée de la sorte :
frame 1 |
frame 3 |
frame 2 |
Nous n'allons pas voir en détail comment créer des frames, c'est là du langage HTML et leur usage a pratiquement disparu.
iframe
est une frame interne à la page. Contrairement aux frame
, ce type d'intégration est très courant, en particulier dans le milieu de la publicité en ligne qui utilise cette technique pour afficher les blocs publicitaires. Une iframe
se crée et se positionne un peu comme une balise div
. La principale différence est que la zone iframe
peut être alimentée en contenu par une adresse définie dans la propriété src
.
<div class="containerIframe"> <iframe class="tuto" id="oneIframe" src="iframe.html"></iframe> </div>
Appliquons quelques éléments de style CSS à notre exemple :
div.containerIframe { text-align:center; paddding:5px; border:1px solid #999; } iframe.tuto { width:220px; height:120px; border:2px solid #FFA500; }
Nous avons donc iframe#oneIframe
entouré en orange et centré à l'intérieur de div.containerIframe
qui charge la page iframe.html
:
Les frame
étant démodées, nous allons concentrer nos exemples sur le cas des iframe
. Le code source serait identique pour des frame
.
Pour changer l'url chargé dans une iframe :
<div class="btn radius btn-sm btn-outline cursor-pointer" onclick="chargerIframe()"> Cliquer pour charger iframe2.html </div>
La fonction pour changer l'attribut src
de l'iframe :
function chargerIframe() { document.querySelector("iframe#oneIframe").setAttribute("src","iframe2.html"); }
Le bouton apparait ici. Cliquez-le pour changer la source de l'iframe de l'exemple plus haut :
Reprenons un exemple d'iframe qui charge la page communique.html
<div class="containerIframe"> <iframe class="tuto" id="myIframe" name="myIframe" src="communique.html"></iframe> <div id="myMessage">En attente de réception de l'iframe...</div> <div class="btn radius btn-sm btn-outline cursor-pointer" onclick="sendMessage('myIframe', 'JE SUIS TON PERE')"> Envoyer un message à l'iframe </div> </div>
Définissons aussi les fonctions receiveMessage(from, txt)
et sendMessage(txt)
dans cette page, contenant l'iframe.
function receiveMessage(from, txt) { document.getElementById("myMessage").innerHTML="Message reçu de l'iframe : '"+txt+"'"; console.log("Message '"+txt+"' reçu de la page "+from); } function sendMessage(to, txt) { window.frames[to].receiveMessage("'"+txt+"'"); console.log("Message '"+txt+"' envoyé à l'iframe name="+to); }
Ce qui donne cet affichage :
Le code source important de l'iframe communique.html
est :
<script type="text/javascript"> /* Lance la fonction receiveMessage sur parent */ function sendMessage(txt) { var from=document.location.href; parent.receiveMessage(from, txt); } /* Reçoit un message de parent */ function receiveMessage(txt) { document.querySelector("div#onIframe").innerHTML="Message reçu : "+txt; } </script> <div class="titre">Page communique.html</div> <div id="onIframe">En attente de réception...</div> <div class="button" onclick="sendMessage('IFRAME')">Send message à parent</div>
Dans l'exemple précédent, l'iframe est hébergée sur le même domaine que la page appelante. L'origine est la même. Le navigateur fait donc confiance à l'iframe qui est considérée comme sure.
Pour des raisons de sécurité, le navigateur interdit toute communication avec une frame qui ne serait pas du même domaine. C'est très utile dans le cas de la publicité. Certaines régies indélicates tentent malgré tout de contourner les protections des navigateurs avec des scripts complexes visant à rediriger tout le trafic naturel du site vers une page dédiée. C'est ce qu'on appelle la faille de sécurité XSS ou Cross Site Scripting.
Utilisons la même iframe communique.html
, avec un fond rouge et hébergée sur un domaine différent et voyons comment il est possible de communiquer :
<div class="containerIframe"> <iframe class="tuto" id="myIframeExterne" name="myIframeExterne" src="https://koala.network/tjs/communique.html"></iframe> <div id="myMessage">En attente de réception de l'iframe...</div> <div class="btn radius btn-sm btn-outline cursor-pointer" onclick="sendMessage('myIframeExterne', 'JE SUIS TON PERE')"> Envoyer un message à l'iframe </div> </div>
Ce qui donne cet affichage :
Tentez de cliquer sur les boutons d'envoi de message. Une erreur est générée et détecté par addEventListener() pour la rendre bien visible...