web-dev-qa-db-ja.com

iframeの動的なサイズ変更

状況:私は典型的なHTML/CSSコンボを含むレスポンシブデザインに取り組んでいます。 div内にiframeがある場合を除き、すべてがうまく機能しています。 iframeは自動的に親divのサイズに調整する必要があります。純粋にcssのソリューションはそれ自体を提示していないので、私はJQueryアプローチを採用します。幅が狭い画面から幅が広い画面にサイズを変更する場合の1つのシナリオを除き、うまく機能します。

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/

問題:ウィンドウのサイズが変更されると、ウィンドウの幅が継続的にチェックされ、480ピクセル未満になると、コードはiframe-class-resizeというクラスを追加して設定しますそのクラスの幅と高さ。ウィンドウのサイズが大きくなると、サイズが480ピクセルに達するとクラスが削除されます。問題は、幅と高さの属性を設定すると、クラス自体ではなく要素に直接追加されることです。したがって、クラスを削除しても、新しい幅と高さは削除されません。 removeAttr()(上記のコメント)を使用して属性を強制的に削除しようとしましたが、うまくいきませんでした。

上記のコードがどこで間違っているのか誰でもわかりますか?または、レスポンシブiframeをより効果的に実現する方法に関する提案はありますか?必要な主なことは、iframeが<div></div>内にある必要があり、divには必ずしも幅または高さが定義されていない場合があることです。理想的には、親divの幅と高さを明示的に定義する必要がありますが、このサイトの現在の設定方法は常に可能ではありません。

追加:上記が十分に明確でない場合は、次を試して問題を再現してください:

  • デスクトップマシンでブラウザを開きます。 WindowsマシンでChromeを使用しています。ブラウザを最大化しないでください。
  • 上記のjsfiddleを開きます( http://jsfiddle.net/TBJ83/ )。 iframeコンテンツがプレビューパネルの幅全体に広がっていることがわかります。
  • ウィンドウ全体が480px未満になるまで、幅を手動で縮小します。この時点で、iframeコンテンツは非常に小さくなります。
  • ウィンドウ全体が>> 480pxになるまで、手動で幅を元のサイズに変更します。目標は、そのiframeコンテンツにプレビューパネルの幅全体を取り戻すことです。代わりに、.css()関数はCSSの変更をクラスではなく要素に直接適用するため、コンテンツはサイズ変更された幅と高さを保持しています。

前もって感謝します!

13
jiminy

これは約30文字で行えます。変化する:

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

に:

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

これにより、要素に適用した幅/高さがリセットされます。 .css()を使用する場合、渡したものを要素のstyle属性に追加します。空白の値を渡すと、jQueryはそのプロパティを要素のstyle属性から削除します。

更新されたフィドルは次のとおりです。 http://jsfiddle.net/TBJ83/3/

[〜#〜] edit [〜#〜]

OK、ここではパフォーマンスのために微調整されたものがあります(および他のいくつかの方法)

_$(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
});
_
9
Jasper

これは、以下のように純粋なCSSを使用して実行できます。

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

高さと幅を必要な最小サイズに設定します。縮小するのではなく、拡大するように見えます。

2
Abhi Andhariya

Prestashopを使用している場合、これがコードの使用方法です。

Cms.tplファイルに、次のコードを追加しました。

{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}

次に、新しいjsファイルformj.jsを作成し、以下のコードを追加しました。

$(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
});
1
keylawnzo

これは私がそれをする方法です、コードははるかに短いです: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>

読みやすさのためにそのようにしましたが、もっと短く、もっと速くすることができます...

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

1つのセレクター。したがって、DOMを複数回ではなく1回だけ参照します。

1
gfrobenius