2014-02-19 14 views
7

Situation: Ich arbeite an einem responsiven Design, das die typische HTML/CSS-Kombination beinhaltet. Alles funktioniert gut, außer in einem Fall, wo ein iframe innerhalb eines divs vorhanden ist. Der Iframe sollte sich automatisch an die Größe des Elternteils anpassen. Eine rein CSS-Lösung hat sich nicht vorgestellt, also gehe ich mit einem JQuery-Ansatz. Es funktioniert gut, außer in einem Szenario, wenn die Größe von einer kleineren Breite zu einer größeren Bildschirmbreite geändert wird.Dynamisch skalieren iframe

HTML:

<div class="container"> 
    <iframe class="iframe-class" src="http://www.cnn.com/"></iframe> 
</div> 

CSS:

.container { 
    width: 100%; 
    height: 250px; 
} 
.iframe-class { 
    width: 100%; 
    height: 100%; 
    border: 1px solid red; 
    overflow: auto; 
} 

Javascript:

$(function() { 
    setIFrameSize(); 
    $(window).resize(function() { 
     setIFrameSize(); 
    }); 
}); 

function setIFrameSize() { 
    var ogWidth = 700; 
    var ogHeight = 600; 
    var ogRatio = ogWidth/ogHeight; 

    var windowWidth = $(window).width(); 
    if (windowWidth < 480) { 
     var parentDivWidth = $(".iframe-class").parent().width(); 
     var newHeight = (parentDivWidth/ogRatio); 
     $(".iframe-class").addClass("iframe-class-resize"); 
     $(".iframe-class-resize").css("width", parentDivWidth); 
     $(".iframe-class-resize").css("height", newHeight); 
    } else { 
     // $(".iframe-class-resize").removeAttr("width"); 
     // $(".iframe-class-resize").removeAttr("height"); 
     $(".iframe-class").removeClass("iframe-class-resize"); 
    } 
} 

http://jsfiddle.net/TBJ83/

Problem: Da das Fenster kleiner Größe verändert wird, ist es die Fensterbreite kontinuierlich überprüft und, sobald es < 480 Pixel trifft, fügt der Code eine Klasse namens iframe-class-resize und legt die Breite und Höhe dieser Klasse. Wenn das Fenster größer skaliert wird, entfernt es die Klasse, sobald die Größe 480 px erreicht. Das Problem besteht darin, dass die Attribute width und height direkt zum Element und nicht zur Klasse selbst hinzugefügt werden. Daher werden beim Entfernen der Klasse die neue Breite und Höhe nicht entfernt. Ich habe versucht, das Entfernen der Attribute mit removeAttr() (kommentiert oben) zu erzwingen, aber das hat nicht funktioniert.

Wer weiß, wo der obige Code falsch gelaufen ist? Oder Vorschläge, wie Sie einen reaktionsfähigen iFrame effizienter erreichen können? Die wichtigsten Dinge, die erforderlich sind, sind, dass der Iframe innerhalb der <div></div> und das Div muss nicht unbedingt eine Breite oder Höhe definiert haben. Im Idealfall sollte das übergeordnete div die Breite und Höhe explizit definiert haben, aber die Art, wie diese Site derzeit eingerichtet ist, ist nicht immer möglich.

Zusätzlich: Falls die oben nicht klar genug war, versuchen Sie folgendes um das Problem zu reproduzieren:

  • einen Browser auf einem Desktop-Rechner öffnen. Ich verwende Chrome auf einem Windows-Computer. Maximiere den Browser nicht.
  • Öffnen Sie die oben genannte Jfiddle (http://jsfiddle.net/TBJ83/). Sie werden feststellen, dass sich der Iframe-Inhalt über die gesamte Breite des Vorschaubereichs erstreckt.
  • Ändern Sie die Breite manuell, bis das gesamte Fenster < 480px ist. An diesem Punkt wird der Iframe-Inhalt ziemlich klein sein.
  • Ändern Sie die Breite manuell, bis das gesamte Fenster >> 480px groß ist. Das Ziel ist, dass der Iframe-Inhalt die gesamte Breite des Vorschaubereichs wieder erreicht. Stattdessen behält der Inhalt die geänderte Breite und Höhe bei, da die Funktion .css() CSS-Änderungen direkt auf Elemente und nicht auf die Klassen anwendet.

Vielen Dank im Voraus!

Antwort

6

Sie können dies in etwa 30 Zeichen tun. Wechsel:

$(".iframe-class").removeClass("iframe-class-resize") 

zu:

$(".iframe-class").removeClass("iframe-class-resize").css({ width : '', height : '' }) 

Dies wird zurückgesetzt, die Breite/Höhe Sie auf das Element angewendet. Wenn Sie .css() verwenden, fügen Sie alles hinzu, was Sie an das Attribut style des Elements übergeben. Wenn Sie einen leeren Wert übergeben, entfernt jQuery diese Eigenschaft aus dem Attribut style des Elements. Hier

ist eine aktualisierte Geige: http://jsfiddle.net/TBJ83/3/

EDIT

OK, hier ist etwas für die Leistung optimiert (und nur ein paar andere Möglichkeiten, Dinge zu tun):

$(function() { 

    //setup these vars only once since they are static 
    var $myIFRAME = $(".iframe-class"),//unless this collection of elements changes over time, you only need to select them once 
     ogWidth  = 700, 
     ogHeight = 600, 
     ogRatio  = ogWidth/ogHeight, 
     windowWidth = 0,//store windowWidth here, this is just a different way to store this data 
     resizeTimer = null; 

    function setIFrameSize() { 
     if (windowWidth < 480) { 

      var parentDivWidth = $myIFRAME.parent().width(),//be aware this will still only get the height of the first element in this set of elements, you'll have to loop over them if you want to support more than one iframe on a page 
       newHeight  = (parentDivWidth/ogRatio); 

      $myIFRAME.addClass("iframe-class-resize").css({ height : newHeight, width : parentDivWidth }); 
     } else { 
      $myIFRAME.removeClass("iframe-class-resize").css({ width : '', height : '' }); 
     } 
    } 

    $(window).resize(function() { 

     //only run this once per resize event, if a user drags the window to a different size, this will wait until they finish, then run the resize function 
     //this way you don't blow up someone's browser with your resize function running hundreds of times a second 
     clearTimeout(resizeTimer); 
     resizeTimer = setTimeout(function() { 
      //make sure to update windowWidth before calling resize function 
      windowWidth = $(window).width(); 

      setIFrameSize(); 

     }, 75); 

    }).trigger("click");//run this once initially, just a different way to initialize 
}); 
+0

Dies funktionierte am besten für meine Situation. Vielen Dank! – jiminy

+0

@jiminy Froh, zu helfen. Ehrlich gesagt hast du ziemlich gut mit deinem Code gearbeitet. Sie können einige Aufrufe verketten und '.css()' Aufrufe kombinieren, indem Sie ein Objekt übergeben. Sie können auch das Verhältnis einmal anstatt jeder Größenänderung berechnen und Ihren resize Event-Handler drosseln. Ansonsten sieht es ziemlich gut aus. Sie könnten vereinfachen, aber auf Kosten der Änderung Ihrer gesamten Methode, und die Einsparungen wären minimal. – Jasper

+0

Ich weiß nicht, schauen Sie, wie viele jQuery Selektoren in diesem Code sind, wie 5. Das ist 5-mal Parsing durch das DOM, um diese Elemente zu finden. Ich habe meins aktualisiert, es tut nur 1 Selektor und benutzt dann das Objekt erneut. – gfrobenius

1

Dies ist, wie ich es tun würde, Code ist viel kürzer: http://jsfiddle.net/TBJ83/2/

<div class="container"> 
    <iframe id="myframe" src="http://www.cnn.com/"></iframe> 
</div> 

<script> 
$(function() { 
    setIFrameSize(); 
    $(window).resize(function() { 
     setIFrameSize(); 
    }); 
}); 

function setIFrameSize() { 
    var parentDivWidth = $("#myframe").parent().width(); 
    var parentDivHeight = $("#myframe").parent().height(); 
    $("#myframe")[0].setAttribute("width", parentDivWidth); 
    $("#myframe")[0].setAttribute("height", parentDivHeight); 
} 
</script> 

ich es für schreib Fähigkeit, diese Art und Weise haben, aber man konnte es machen noch kürzer und schneller ...

function setIFrameSize() { 
    f = $("#myframe"); 
    f[0].setAttribute("width", f.parent().width()); 
    f[0].setAttribute("height", f.parent().height()); 
} 

Ein Selektor, so dass Sie nur einmal durch das DOM statt mehrmals schauen.

+0

Das Geige scheint nicht das hartcodierte Seitenverhältnis, wenn sie unter 480px breit zu respektieren. – Jasper

+0

Das funktionierte in meinem Fall nicht. Allerdings mag ich die Idee, und ich werde es immer noch im Auge behalten für zukünftige Referenz. Vielen Dank! – jiminy

0

Für diejenigen mit Prestashop, so habe ich den Code benutzt.

In der cms.tpl Datei habe ich den folgenden Code:

{if $cms->id==2} 
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js?ver=1.3.2'></script> 
<script type="text/javascript" src='../themes/myheme/js/formj.js'></script> 
<div style="width: 100%; height: 800px;"> 
<iframe style=" width: 100%; height: 100%; border: overflow: auto;" src="https://cnn.com"></iframe> 
</div> 
{/if} 

Dann eine neue js Datei erstellt: formj.js und hinzugefügt, um den folgenden Code:

$(function() { 

    //setup these vars only once since they are static 
    var $myIFRAME = $(".iframe-class"),//unless this collection of elements changes over time, you only need to select them once 
     ogWidth  = 970, 
     ogHeight = 800, 
     ogRatio  = ogWidth/ogHeight, 
     windowWidth = 0,//store windowWidth here, this is just a different way to store this data 
     resizeTimer = null; 

    function setIFrameSize() { 
     if (windowWidth < 480) { 

      var parentDivWidth = $myIFRAME.parent().width(),//be aware this will still only get the height of the first element in this set of elements, you'll have to loop over them if you want to support more than one iframe on a page 
       newHeight  = (parentDivWidth/ogRatio); 

      $myIFRAME.addClass("iframe-class-resize").css({ height : newHeight, width : parentDivWidth }); 
     } else { 
      $myIFRAME.removeClass("iframe-class-resize").css({ width : '', height : '' }); 
     } 
    } 

    $(window).resize(function() { 

     //only run this once per resize event, if a user drags the window to a different size, this will wait until they finish, then run the resize function 
     //this way you don't blow up someone's browser with your resize function running hundreds of times a second 
     clearTimeout(resizeTimer); 
     resizeTimer = setTimeout(function() { 
      //make sure to update windowWidth before calling resize function 
      windowWidth = $(window).width(); 

      setIFrameSize(); 

     }, 75); 

    }).trigger("click");//run this once initially, just a different way to initialize 
}); 
0

Dies kann getan werden, mit reinem CSS wie folgt:

iframe { 
    height: 300px; 
    width: 300px; 
    resize: both; 
    overflow: auto; 
} 

die Höhe und Breite auf die Mindestgröße einstellen Sie wollen, es scheint nur zu wachsen, nicht schrumpfen.

Verwandte Themen