wake-up-neo.net

Ändern Sie dynamisch die Größe von iframe

Situation: Ich arbeite an einem Responsive Design, das die typische HTML/CSS-Combo beinhaltet. Alles funktioniert gut, außer in einem Fall, in dem ein iframe in einem div vorhanden ist. Der iframe sollte sich automatisch an die Größe des übergeordneten div anpassen. Eine reine css-Lösung hat sich noch nicht präsentiert, daher gehe ich auf einen JQuery-Ansatz. Es funktioniert gut, außer in einem Szenario, wenn Sie die Größe von einem kleineren Bildschirm auf einen größeren Bildschirm ändern.

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: Wenn das Fenster verkleinert wird, überprüft es kontinuierlich die Fensterbreite. Sobald es <480 px erreicht, fügt der Code eine Klasse mit dem Namen iframe-class-resize hinzu und legt die Breite und Höhe dieser Klasse fest. Wenn die Größe des Fensters größer wird, wird die Klasse entfernt, sobald die Größe 480 Pixel erreicht. Das Problem ist, dass durch das Setzen der Attribute width und height sie direkt dem Element und nicht der Klasse selbst hinzugefügt werden. Beim Entfernen der Klasse werden die neue Breite und Höhe daher nicht entfernt. Ich habe versucht, die Entfernung der Attribute mit Hilfe von removeAttr() zu erzwingen (oben kommentiert), aber das hat nicht funktioniert.

Weiß jemand, wo der Code oben schief ging? Oder irgendwelche Vorschläge, wie man einen reaktionsschnellen Iframe effektiver erreichen kann? Die wichtigsten Dinge, die erforderlich sind, sind, dass sich der iframe im <div></div> befinden muss und das div nicht unbedingt eine definierte Breite oder Höhe haben muss. Im Idealfall sollte die Breite und Höhe des übergeordneten div explizit definiert sein, aber die Art und Weise, in der diese Site derzeit eingerichtet ist, ist nicht immer möglich.

Additional: Falls das oben Genannte nicht klar genug ist, versuchen Sie, das Problem zu reproduzieren:

  • Öffnen Sie einen Browser auf einem Desktop-Computer. Ich verwende Chrome auf einem Windows-Computer. Maximieren Sie den Browser nicht.
  • Öffnen Sie das jsfiddle oben ( http://jsfiddle.net/TBJ83/ ). Sie werden feststellen, dass der iframe-Inhalt die gesamte Breite des Vorschaufensters umfasst.
  • Verändern Sie die Breite manuell, bis das gesamte Fenster <480px ist. Zu diesem Zeitpunkt ist der Inhalt des Iframes ziemlich klein.
  • Ändern Sie die Breite manuell erneut, bis das gesamte Fenster >> 480px ist. Das Ziel ist, dass dieser iframe-Inhalt die gesamte Breite des Vorschaubereichs wiederherstellt. Stattdessen behält der Inhalt die Breite und Höhe in der Größe bei, da die .css()-Funktion Änderungen von CSS direkt auf Elemente und nicht auf Klassen anwendet.

Danke im Voraus!

8
jiminy

Sie können dies in etwa 30 Zeichen tun. Veränderung:

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

zu:

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

Dadurch wird die Breite/Höhe, die Sie dem Element zugewiesen haben, zurückgesetzt. Wenn Sie .css() verwenden, fügen Sie das, was Sie übergeben, dem style-Attribut des Elements hinzu. Wenn Sie einen leeren Wert übergeben, entfernt jQuery diese Eigenschaft aus dem style-Attribut des Elements.

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

EDIT

OK, hier ist etwas für die Performance (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
});
8
Jasper

So würde ich es machen, der 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 habe es auf diese Weise für die Lesefähigkeit gemacht, aber Sie könnten es noch kürzer und schneller machen ...

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

Eine Auswahl, sodass Sie das DOM nur einmal und nicht mehrmals durchsehen.

1
gfrobenius

Dies kann mit reinem CSS wie folgt durchgeführt werden:

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

Stellen Sie die Höhe und Breite auf die gewünschte Mindestgröße ein, es scheint nur zu wachsen, nicht zu schrumpfen.

0
Abhi Andhariya

Für diejenigen, die Prestashop verwenden, habe ich den Code so verwendet.

In der cms.tpl-Datei habe ich den folgenden Code hinzugefügt:

{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 erstellte eine neue js-Datei: formj.js und fügte den folgenden Code hinzu:

$(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
keylawnzo