====== Ajuster dynamiquement la hauteur des " remplit cette condition (sans css) puisque //body// prend naturellement 100% du port de restitution (fenêtre). Un code simple tel que : effectuera l'ajustement automatique de la taille de l'iframe, __sur certains navigateurs__, à condition que l'iframe tienne dans son conteneur (fenêtre, bloc, etc.). Certains navigateurs appliqueront une taille par défaut les conduisant à tronquer le contenu de l'iframe. Dans tous les cas, si le contenu de l'iframe excède la taille de la fenêtre (le plus grand conteneur possible), il sera irrémédiablement tronqué. Si l'attribut "scrolling" était fixé à "yes", des ascenseurs internes seraient créés, mais tel n'est pas le but recherché. On souhaite que la circulation dans le contenu de l'iframe se fasse au moyen ascenseurs de la fenêtre de visualisation, comme s'il s'agissait d'un contenu "natif" de la page affichée. Pour cela, il faut que l'iframe soit automatiquement affiché en "pleine page", même si du contenu déborde de la fenêtre. ===== Forcer le redimentionnement ===== Votre page va devoir faire appel à Javascript. Vous devrez donc prévoir une alternative. Le seul moyen de garantir que le contenu de l'iframe occupera toute la place qui lui est nécessaire sur la page-hôtesse est de forcer le redimensionnement de l'espace qui lui est accordé, une fois que l'on connaît l'espace nécessaire, donc **après chargement** du contenu de l'iframe. Ce "redimentionnement" a posteriori ne peut être effectué que par un code javascript. Si le principe est simple, il faut envisager le cas où la source chargée dans l'iframe n'est pas dans le domaine de la page-hôtesse. En effet, afin d'éviter qu'un iframe que l'on ne contrôle pas vienne interagir avec le code javascript de la page-hôtesse, les navigateurs bloquent ce genre d'interacton ([[http://en.wikipedia.org/wiki/Same_origin_policy|Same origin policy]]) ! Nous verrons qu'il existe des moyens de contourner cette limitation de sécurité. Enfin, la simplicité du principe se heurte aux facéties d'implémentation des différents navigateurs Web, en particulier d'IE. Toute solution devra donc être testée sur les navigateurs pour lesquels on souhaite qualifier la page-hôtesse. ==== Même domaine ==== Lorsque la page-hôtesse et l'iframe partagent le même nom de domaine, il existe de nombreuses solutions permettant de résoudre ce problème récurrent de taille des iframes. Ma priorité du moment allant aux iframes inter-domaines, le champ d'application intra-domaine a été survolé. === jquery-iframe-auto-height === S'appuyant sur la bibliothèque jQuery, [[https://github.com/house9/jquery-iframe-auto-height|jquery-iframe-auto-height]] propose une solution simple à mettre en œuvre. Dans l'exemple suivant, on se contente d'ajouter un code javasript __à la suite__ de l'élément iframe que l'on veut redimensionner : Dans cet exemple, le redimentionnement est limité aux iframes de la classe "hauteur-auto" et l'on impose une hauteur minimale, dans l'éventualité où la hauteur nécessaire au contenu de l'iframe serait inférieure à cette valeur. Après s'être assuré que la bibliothèque //jQuery// et le //plugin jquery-iframe-auto-height// sont effectivement chargés par la page, on n'oubliera pas d'insérer un déclencheur de redimentionnement, dans la page-hôtesse, de préférence dans le //head// : Pour une description complète des options, paramètres et fonctionnalités, se reporter à la [[https://github.com/house9/jquery-iframe-auto-height#readme|documentation de jquery-iframe-auto-height]]. === jQuery Auto Iframe Height === Source : [[http://www.lost-in-code.com/programming/jquery-auto-iframe-height/|tutoriel]] (blog - en). [[http://www.lost-in-code.com/wp-content/uploads/2012/01/jquery.autoheight.js|Auto Iframe Height]] est un plugin jQuery plus rustique que le précédent mais plus simple à mettre en œuvre. Il suffit de charger jQuery et jquery.autoheight (dans le //head//) : On déclare ses iframes comme d'habitude. On n'a plus qu'à les rattacher à la classe //autoHeight// (mot réservé du plugin) : === Drupal === Sous Drupal, le module [[https://drupal.org/project/insertFrame|InsertFrame]] se charge de l'essentiel du travail. Dans un champ de contenu correctement configuré, on se contente d'insérer l'url de l'iframe : [[[http://mondomaine.tld/mon_application.html]]] Se reporter à la [[https://drupal.org/node/602268|documentation du module]] pour les précisions : syntaxe, paramètres et configuration du champ de saisie. === Bricolages divers === De multiples propositions en javascript "pur" fleurissent ici et là. Si elles présentent un intérêt pédagogique la plupart n'ont pas la robustesse souhaitée (cas d'utilisation, navigateurs, …). Sans préjuger de la validité de toutes les solutions proposées, aucune de celles testées n'a donné de résultat satisfaisant. Ça doit pourtant être possible puisque nous avons trouvé une solution fonctionnelle pour les iframes inter-domaines (voir plus loin). ==== Domaines différents ==== Si l'interaction entre pages issues de domaines différents est une source de risque de sécurité, c'est parfois le comportement souhaité. Vous devrez non seulement modifier la page-hôtesse mais aussi le code de la page-invitée dans l'iframe. === Pure Javascript === Sources : [[http://stackoverflow.com/questions/153152/resizing-an-iframe-based-on-content|explication]] (blog -en). Une technique n'utilisant que les fonctions de base de javascript (sans bibliothèque additionnelle) permet de contourner la difficulté. Elle mobilise une page purement technique, indépendante de tout contenu, qui va permettre la transmission d'information depuis la page-invitée vers la page-hôtesse: la page-messagère. La page-hôtesse et la page-messagère doivent impérativement appartenir au même domaine. Suivant les règles de sécurité, la page-hôtesse peut communiquer avec la page-invitée (fille), la page-messagère peut communiquer avec la page-hôtesse (même domaine). Il ne reste plus qu'à permettre la communication entre la page-invitée et la page-messagère. Pour ce faire, il suffit d'inclure, __par iframe__, la page-messagère dans la page-invitée. On a alors le schéma de communication suivant; hôtesse > invitée > messagère > hôtesse. La page invitée peut désormais transmettre des informations (comme sa taille) à sa page hôtesse, par l'intermédiaire de la page-messagère. Voici des exemples du code qu'il faudra insérer dans chacune des pages : page-hôtesse (http://mon.domaine.tld/index.html) page-invitée (http://domaine.externe.tld/application/framed.html) page-messagère (http://mon.domaine.tld/messagere.html) === HMTL 4 avec easyXDM=== Source : [[http://easyxdm.net/wp/2010/03/17/resize-iframe-based-on-content/|Resize iframe based on content]] (blog -en). Si l'on utilise html 4, la bibliothèque [[http://easyxdm.net/|easyXDM]] (Cross-Domain Messaging made easy) est là pour nous aider à contourner la limitation de l'interaction inter-domaines. Comme dans le cas de domaines identiques, on devra adapter la page-hôtesse. Mais l'**on devra également modifier le contenu de la page invitée** dans l'iframe ! Dans le code source de la page page-hôtesse, l'élément //iframe// est remplacé par un objet javascript que l'on déclarera dans un élément //script// de l'élément //head// : new easyXDM.Socket({ remote: "http://provider.easyxdm.net/example/resized_iframe.html", container: document.getElementById("container"), onMessage: function(message, origin){ this.container.getElementsByTagName("iframe")[0].style.height = message + "px"; } }); ici, "container" (ligne 3) est à remplacer par l'id de l'élément html dans lequel on souhaite insérer la page-invitée (par ex.
). Dans la page-invitée, on ajoute le code javascript suivant, à la suite du contenu : var socket = new easyXDM.Socket({ onReady: function(){ socket.postMessage(document.body.scrollHeight) } }); Cette technique exige une mise en œuvre plus sophistiquée si l'on veut permettre la navigation dans l'iframe (pas simplement afficher une page). Afin d'assurer la navigation dans l'iframe ouvert, il convient de créer un iframe intermédiaire ([[http://provider.easyxdm.net/current/example/resize_intermediate.html|voir exemple]]). La page-hôtesse invite cette page intermédiaire en lui fournissant comme paramètre l'url de la page d'accueil invitée ([[http://consumer.easyxdm.net/current/example/resize_iframe.html|voir exemple]]). Enfin, toute page invitée affichée au cours de la navigation doit avoir été modifiée en conséquence ([[http://provider.easyxdm.net/current/example/resized_iframe_1.html|voir exemple]]). == Variante == Dans la page-hôtesse var transport = new easyXDM.transport.BestAvailableTransport({ local: "../hash.html", remote: "http://provider.easyxdm.net/example/resized_iframe.html", container: document.getElementById("element_that_should_contain_the_frame"), onMessage: function(message, origin){ this.container.getElementsByTagName("iframe")[0].style.height = message + "px"; } }); Dans chaque page-invitée, à la suite du contenu : var transport = new easyXDM.transport.BestAvailableTransport({}, function(){ transport.postMessage(document.body.scrollHeight); }); === HMTL 5=== Sources : [[http://www.w3.org/TR/webmessaging/#web-messaging|la norme]] (w3c - en), [[https://en.wikipedia.org/wiki/Cross-document_messaging|le principe]] (wp - en), [[https://developer.mozilla.org/en-US/docs/DOM/window.postMessage|une explication fouillée]] (mozzila - en), [[http://stackoverflow.com/questions/5908676/yet-another-cross-domain-iframe-resize-qa|un exemple]] __sauter les premiers messages__ (blog - en). Html 5 intègre l'API de communication inter-domaines par échange de messages entre fenêtres ou frames. S'appuyant sur le même principe que easyXDM, on retrouve la même chose à quelques variations près. Dans la page invitée : ... ... Ici, //element_id// sera replacé par l'id de l'élément de la page invitée dont on souhaite transmettre la hauteur ((Dans le cas le plus grossier et le plus courant, l'élément //body// est un bon candidat. Dans ce cas (élément unique dans un document valide), on peut adapter le code javascript pour récupérer la propriété de l'élément par son nom de balise, ce qui évite de mobiliser un attribut //id// que l'on ne maîtrise pas nécessairement (par ex., génération dynamique).)). Dans la page-hôtesse : puis on insère un élément //iframe//, sans oublier de déclarer son //id// en cohérence avec le choix fait dans le code précédent (ici "mon_iframe_id").