521 votes

Redimensionnement d’un iframe basé sur le contenu

Je travaille sur une application iGoogle-like. Contenu provenant d’autres applications (sur les autres domaines) est affiché à l’aide des iframes.

Comment pour redimensionner les iframes pour s’adapter à la hauteur du contenu de l’IFRAME ?

J’ai essayé de déchiffrer le javascript Google utilise mais elle est masquée, et le web à la recherche a été vaine jusqu'à présent.

Mise à jour : S’il vous plaît note que le contenu est chargé dans d’autres domaines, donc la même origine politique s’applique.

594voto

ConroyP Points 24021

Nous avons eu ce type de problème, mais légèrement dans le sens inverse de votre situation, nous étions en fournissant les iframed contenu des sites sur d'autres domaines, de sorte que la même politique d'origine a également été un problème. Après de nombreuses heures de chalutage de google, nous avons finalement trouvé une (un peu..) solution viable, que vous pouvez être en mesure de s'adapter à vos besoins.

Il y a un moyen de contourner la même origine, mais cela exige des changements à la fois sur les iframed contenu et de la formulation de la page, donc si vous n'avez pas la possibilité de demander des modifications sur les deux côtés, cette méthode ne sera pas très utile pour vous, je le crains.

Il y a un navigateur caprice qui nous permet de jupe de la même origine - javascript peut communiquer soit avec des pages sur son propre domaine, ou avec des pages qu'il a iframed, mais jamais les pages dans lesquelles il est encadré, par exemple, si vous avez:

 www.foo.com/home.html, which iframes
 |-> www.bar.net/framed.html, which iframes
     |-> www.foo.com/helper.html

ensuite, home.html pouvez communiquer avec framed.html (iframed) et helper.html (même domaine).

 Communication options for each page:
 +-------------------------+-----------+-------------+-------------+
 |                         | home.html | framed.html | helper.html |
 +-------------------------+-----------+-------------+-------------+
 | www.foo.com/home.html   |    N/A    |     YES     |     YES     |
 | www.bar.net/framed.html |    NO     |     N/A     |     YES     |
 | www.foo.com/helper.html |    YES    |     YES     |     N/A     |
 +-------------------------+-----------+-------------+-------------+

framed.html pouvez envoyer des messages à d' helper.html (iframed) mais pas home.html (l'enfant ne peut pas communiquer inter-domaines avec un parent).

La clé ici est que l' helper.html pouvez recevoir des messages d' framed.html, et peut également communiquer avec home.html.

Donc, essentiellement, lorsqu' framed.html charge, il fonctionne de son propre hauteur, dit helper.html, qui transmet le message à l' home.html, qui peut ensuite redimensionner l'iframe dans lequel framed.html siège.

La façon la plus simple que nous avons trouvé pour faire passer des messages à partir d' framed.html de helper.html a été par le biais d'un argument URL. Pour ce faire, framed.html a un iframe avec src='' spécifié. Lors de son onload des incendies, il évalue sa propre hauteur, et définit la src de l'iframe à ce point de helper.html?height=N

Il y a une explication ici comment facebook le gérer, ce qui peut être légèrement plus claire que la mienne ci-dessus!


Code

En www.foo.com/home.html, le code javascript suivant est nécessaire (cela peut être chargé à partir d'un .fichier js sur un domaine, d'ailleurs..):

<script>
  // Resize iframe to full height
  function resizeIframe(height)
  {
    // "+60" is a general rule of thumb to allow for differences in
    // IE & and FF height reporting, can be adjusted as required..
    document.getElementById('frame_name_here').height = parseInt(height)+60;
  }
</script>
<iframe id='frame_name_here' src='http://www.bar.net/framed.html'></iframe>

En www.bar.net/framed.html:

<body onload="iframeResizePipe()">
<iframe id="helpframe" src='' height='0' width='0' frameborder='0'></iframe>

<script type="text/javascript">
  function iframeResizePipe()
  {
     // What's the page height?
     var height = document.body.scrollHeight;

     // Going to 'pipe' the data to the parent through the helpframe..
     var pipe = document.getElementById('helpframe');

     // Cachebuster a precaution here to stop browser caching interfering
     pipe.src = 'http://www.foo.com/helper.html?height='+height+'&cacheb='+Math.random();

  }
</script>

Contenu de www.foo.com/helper.html:

<html> 
<!-- 
This page is on the same domain as the parent, so can
communicate with it to order the iframe window resizing
to fit the content 
--> 
  <body onload="parentIframeResize()"> 
    <script> 
      // Tell the parent iframe what height the iframe needs to be
      function parentIframeResize()
      {
         var height = getParam('height');
         // This works as our parent's parent is on our domain..
         parent.parent.resizeIframe(height);
      }

      // Helper function, parse param from request string
      function getParam( name )
      {
        name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
        var regexS = "[\\?&]"+name+"=([^&#]*)";
        var regex = new RegExp( regexS );
        var results = regex.exec( window.location.href );
        if( results == null )
          return "";
        else
          return results[1];
      }
    </script> 
  </body> 
</html>

77voto

Ahmy Points 2612

Si vous n’avez pas besoin de gérer le contenu iframe d’un autre domaine, essayez ce code, il ne résoudra pas le problème complètement, et c’est simple :

42voto

Chris Jacob Points 4211

https://developer.mozilla.org/en/DOM/window.postMessage

de la fenêtre.postMessage()

de la fenêtre.postMessage est une méthode en toute sécurité pour l'activation de la croix-origine de la communication. Normalement, les scripts sur les différentes pages ne sont autorisés à accéder aux autres si et seulement si les pages qui les ont exécutés sont à des endroits avec le même protocole (généralement http), le numéro de port (80 par défaut pour http), et l'hôte (modulo document.domaine défini par les deux pages de la même valeur). de la fenêtre.postMessage fournit un mécanisme de contrôle de contourner cette restriction dans une manière qui est sûr lorsqu'il est correctement utilisé.

Résumé

de la fenêtre.postMessage, lorsqu'il est appelé, provoque une classe messageevent à être envoyé à la cible de la fenêtre lors de la toute attente script doit être exécuté complète (par exemple, en restant gestionnaires d'événements si la fenêtre.postMessage est appelée à partir d'un gestionnaire d'événement, précédemment fixé les délais d'attente, etc.). La classe messageevent a le type de messages, de données, de la propriété qui est la chaîne de valeur du premier argument fourni à la fenêtre.postMessage, l'origine de propriété correspondant à l'origine du document principal dans la fenêtre de la fenêtre appelante.postMessage à la fenêtre de temps.postMessage a été appelé, et une source de la propriété qui est la fenêtre à partir de laquelle la fenêtre.postMessage est appelé. (D'autres propriétés standard des événements sont présents avec leurs valeurs attendues.)

L' iFrame-Resizer bibliothèque utilise postMessage pour garder un iFrame de la taille de son contenu, avec MutationObserver pour détecter les modifications de contenu et ne dépend pas de jQuery.

https://github.com/davidjbradshaw/iframe-resizer

jQuery: Cross-domain scripting bonté

http://benalman.com/projects/jquery-postmessage-plugin/

A la démo de redimensionnement de la fenêtre iframe...

http://benalman.com/code/projects/jquery-postmessage/examples/iframe/

Cet article montre comment faire pour supprimer la dépendance sur jQuery... en Plus a beaucoup d'infos utiles et des liens vers d'autres solutions.

http://www.onlineaspect.com/2010/01/15/backwards-compatible-postmessage/

Barebones exemple...

http://onlineaspect.com/uploads/postmessage/parent.html

HTML 5, document de travail de la fenêtre.postMessage

http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages

John Resig sur la Fenêtre de Messagerie

http://ejohn.org/blog/cross-window-messaging/

8voto

Omer Arshad Points 199

La façon la plus simple à l’aide de jQuery :

6voto

Macho Matt Points 595

La solution sur http://www.phinesolutions.com/use-jquery-to-adjust-the-iframe-height.html fonctionne très bien (utilise jQuery) :

Je ne sais pas que vous deviez ajouter 30 à la longueur... 1 a fonctionné pour moi.

FYI: Si vous avez déjà un attribut « height » sur votre iFrame, cela ne fait qu’ajouter style = "height : xxx ». Cela ne pourrait pas être ce que vous voulez.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X