jqueryはロード時にiframeコンテンツの高さを取得します


84

main.phpのiframe内にロードしているヘルプページhelp.phpがあります。iframeにロードされた後、このページの高さを取得するにはどうすればよいですか?

iframeの高さを100%または自動にスタイル設定できないため、これを求めています。だから私はjavascriptを使う必要があると思います。私はjQueryを使っています

CSS:

body {
    margin: 0;
    padding: 0;
}
.container {
    width: 900px;
    height: 100%;
    margin: 0 auto;
    background: silver;
}
.help-div {
    display: none;
    width: 850px;
    height: 100%;
    position: absolute;
    top: 100px;
    background: orange;
}
#help-frame {
    width: 100%;
    height: auto;
    margin:0;
    padding:0;
}

JS:

$(document).ready(function () {
    $("a.open-help").click(function () {
        $(".help-div").show();
        return false;
    })
})

HTML:

<div class='container'>
    <!-- -->
    <div class='help-div'>
        <p>This is a div with an iframe loading the help page</p>
        <iframe id="help-frame" src="../help.php" width="100%" height="100%" frameborder="1"></iframe>
    </div>  <a class="open-help" href="#">open Help in iFrame</a>

    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
    <p>hello world</p>
</div>

iFrameのコンテンツは、それが含まれているページと同じドメインからのものですか?
アンドリュー

回答:


102

わかりました、私はついに良い解決策を見つけました:

$('iframe').load(function() {
    this.style.height =
    this.contentWindow.document.body.offsetHeight + 'px';
});

一部のブラウザ(古いSafariおよびOpera)は、CSSがレンダリングされる前にオンロードが完了したと報告するため、マイクロタイムアウトを設定し、iframeのsrcを空白にして再割り当てする必要があります。

$('iframe').load(function() {
    setTimeout(iResize, 50);
    // Safari and Opera need a kick-start.
    var iSource = document.getElementById('your-iframe-id').src;
    document.getElementById('your-iframe-id').src = '';
    document.getElementById('your-iframe-id').src = iSource;
});
function iResize() {
    document.getElementById('your-iframe-id').style.height = 
    document.getElementById('your-iframe-id').contentWindow.document.body.offsetHeight + 'px';
}

このソリューションは、上記がコンテナ内のiframeコンテンツからサイズを取得するのに対し、これがrealサイズを取得するため、
うまく機能

2
ロードイベントは同じイベントループでトリガーされるため、1ミリ秒のsetTimoutも同様に機能すると思います
George Mauer

hhmmm親をロードするときに非表示になっているiframeの高さを取得する方法は誰でも知っています。この方法では、バック0をもたらします
JT ...

1
document高さではなく、body高さが必要な場合があります。jQueryを使用すると、で取得できます$(this.contentWindow.document).height()
vpiTriumph 2013年

古いもの、つまりiframe.contentDocument.body.offsetHeightは機能します。stackoverflow.com/questions/2684693/...
user1087079

50

それほど複雑ではない答えは.contents()、iframeを取得するために使用することです。ただし、興味深いことに、本文のパディングが原因で、元の回答のコードを使用して取得した値とは異なる値が返されると思います。

$('iframe').contents().height() + 'is the height'

これが私がクロスドメイン通信のためにそれをした方法です、それで私はそれが多分不必要に複雑であるのではないかと心配しています。まず、jQueryをiFrameのドキュメント内に配置します。これにより多くのメモリが消費されますが、スクリプトを1回ロードするだけでよいため、ロード時間が長くなることはありません。

iFrameのjQueryを使用してiframeの本体の高さをできるだけ早く測定し(onDOMReady)、URLハッシュをその高さに設定します。また、親ドキュメントでonload、iFrameタグにイベントを追加して、iframeの場所を確認し、必要な値を抽出します。onDOMReadyは常にドキュメントのロードイベントの前に発生するため、競合状態が複雑になることなく、値が正しく伝達されることをかなり確信で​​きます。

言い換えると:

... Help.phpで:

var getDocumentHeight = function() {
    if (location.hash === '') { // EDIT: this should prevent the retriggering of onDOMReady
        location.hash = $('body').height(); 
        // at this point the document address will be something like help.php#1552
    }
};
$(getDocumentHeight);

...そして親ドキュメント:

var getIFrameHeight = function() {
    var iFrame = $('iframe')[0]; // this will return the DOM element
    var strHash = iFrame.contentDocument.location.hash;
    alert(strHash); // will return something like '#1552'
};
$('iframe').bind('load', getIFrameHeight );

こんにちはアンドリューこれまでのところ非常に良い助けがここにあります。contents()はうまく機能しますが、それでも帯域幅スロットルでテストする必要があります。たぶん、innerHeight()プロパティを使用できます。高さをハッシュに入れてソリューションを使用するFF(OSX)に問題があります。FFはgetDocumentHeight()関数を不定詞ループでロードし続けているようですか?Safariは罰金..です
FFish

面白い。すでに値が存在する場合にハッシュの設定を防ぐチェックを追加しました。Help.phpにハッシュ値(例<iframe src="../Help.php#introduction" />)をロードする場合は、これを微調整する必要があるかもしれません
Andrew

ちなみに、高さの違いを調整できるとすれば、iframeの外で通信するためにハッシュを使用する必要はおそらくないでしょう。ハッシュメソッドを使用する場合sleep(5)は、Help.phpにを入れることも、競合状態をテストするための良い方法です。iframeがonLoad以前onDOMReadyに何らかの理由で起動した場合は、ここに表示されます。
アンドリュー

23

Chrome、Firefox、IE11で動作するものは次のとおりです。

$('iframe').load(function () {
    $('iframe').height($('iframe').contents().height());
});

Iframesコンテンツの読み込みが完了すると、イベントが発生し、IFramesの高さがコンテンツの高さに設定されます。これは、IFrameと同じドメイン内のページでのみ機能します。


正常に動作しますが、幅については、このようにする必要があります。そうしないと、コンテンツがカットされます$( 'iframe')。width($( 'iframe')。contents()。width()+ 30);
geomorillo 2014

@AminGhaderiはFirefox40.0.3で問題なく動作します
mixkat 2015

@mixkat私はこのソリューションとこのトピックのすべてのソリューションを介してiframeにWebサイトをロードしますが、私にとっては機能しません!このソリューションは1ページで機能し、完全なWebサイトをiframeにロードしても機能しないと思います。私の英語はとても下手です、あなたが理解してくれることを願っています。
アミンガデリ2015

@AminGhaderiこれが正しければ、サイトのすべてのページで機能することを期待できますが、フレームの読み込み時に1回しか実行されないため、もちろんすべてのページで機能するとは限りません。したがって、最初のページでは問題なく機能しますが、より長いページで機能させたい場合は、新しいページでフレームを再度ロードするか、の別の時点でcontents.heightを呼び出すことによって再度実行する必要があります。あなたの流れ
mixkat 2015

9

jQueryなしでこれを行うコードは、最近では簡単です。

const frame = document.querySelector('iframe')
function syncHeight() {
  this.style.height = `${this.contentWindow.document.body.offsetHeight}px`
}
frame.addEventListener('load', syncHeight)

イベントのフックを解除するには:

frame.removeEventListener('load', syncHeight)

3
素晴らしくてシンプル!残念ながら、クロスドメインiframeでは機能しません:(
TimoSolo 2018年

3
うん、運が悪かった。そのためにiframe-resizerライブラリを活用します。もちろん、それが機能するためには、両方のドメインを制御する必要があります。
cchamberlain

6

これを行うためにiframe内にjqueryは必要ありませんが、コードが非常に単純であるため、これを使用します...

これをiframe内のドキュメントに入れます。

$(document).ready(function() {
  parent.set_size(this.body.offsetHeight + 5 + "px");  
});

小さなウィンドウのスクロールバーをなくすために上記の5つを追加しましたが、サイズが完璧になることはありません。

そして、これはあなたの親文書の中にあります。

function set_size(ht)
{
$("#iframeId").css('height',ht);
}

これは、iframe内にPDFを表示している場合にも機能しません。
Jason Foglia 2014年

申し訳ありませんが、「フレーム内」の例は明らかにjQueryベースです。
T-moty

4

これは私のために働いた正解です

$(document).ready(function () {
        function resizeIframe() {
            if ($('iframe').contents().find('html').height() > 100) {
                $('iframe').height(($('iframe').contents().find('html').height()) + 'px')
            } else {
                setTimeout(function (e) {
                    resizeIframe();
                }, 50);
            }
        }
        resizeIframe();
    });

4

単純なワンライナーは、デフォルトの最小の高さで始まり、コンテンツのサイズまで増加します。

<iframe src="http://url.html" onload='javascript:(function(o){o.style.height=o.contentWindow.document.body.scrollHeight+"px";}(this));' style="height:200px;width:100%;border:none;overflow:hidden;"></iframe>



1

これは、iframe内のSPAで動作できるjQueryフリーのソリューションです

document.getElementById('iframe-id').addEventListener('load', function () {
  let that = this;
  setTimeout(function () {
    that.style.height = that.contentWindow.document.body.offsetHeight + 'px';
  }, 2000) // if you're having SPA framework (angularjs for example) inside the iframe, some delay is needed for the content to populate
});

1

これは私のES6フレンドリーなno-jqueryテイクです

document.querySelector('iframe').addEventListener('load', function() {
    const iframeBody = this.contentWindow.document.body;
    const height = Math.max(iframeBody.scrollHeight, iframeBody.offsetHeight);
    this.style.height = `${height}px`;
});
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.