内部のコンテンツに基づいてiframeの高さを動的にする-JQUERY / Javascript


202

iframeにaspx Webページを読み込んでいます。iframeのコンテンツは、iframeの高さよりも高い場合があります。iframeにはスクロールバーを含めないでください。

div基本的にすべてのコンテンツであるiframe内にラッパータグがあります。サイズ変更を行うためにいくつかのjQueryを作成しました。

$("#TB_window", window.parent.document).height($("body").height() + 50);

どこ TB_windowここでdiv要素であるIframe含まれています。

body -iframe内のaspxのbodyタグ。

このスクリプトはiframeコンテンツに添付されています。TB_window親ページから要素を取得しています。これはChromeでは問題なく動作しますが、TB_windowはFirefoxでは折りたたまれます。私はそれがなぜ起こるのか本当に混乱しています/迷っています。


その.aspx iframeページは同じドメイン名からのものですか?
AlexC

$( "body")。height()がFirefoxで値を持っていることを確認できますか?
マイケルLワトソン

はい。iframeはコンテナページと同じドメインにあります
karry

@MichaelLWatson Firebugウォッチウィンドウのボディの高さは0のように見えますが、Chromeには値があります
karry

回答:


212

を使用して、IFRAMEのコンテンツの高さを取得できます。 contentWindow.document.body.scrollHeight

IFRAMEが読み込まれた後、次のようにして高さを変更できます。

<script type="text/javascript">
  function iframeLoaded() {
      var iFrameID = document.getElementById('idIframe');
      if(iFrameID) {
            // here you can make the height, I delete it first, then I make it again
            iFrameID.height = "";
            iFrameID.height = iFrameID.contentWindow.document.body.scrollHeight + "px";
      }   
  }
</script>   

次に、IFRAMEタグで、次のようにハンドラーをフックします。

<iframe id="idIframe" onload="iframeLoaded()" ...

少し前に、フォームの送信が行われた後iframeLoadedIFRAME自分自身からさらに呼び出す必要がある状況がありました。IFRAMEのコンテンツスクリプト内で以下を実行することにより、これを実現できます。

parent.iframeLoaded();

153
クロスドメインではサポートしていません。
Soumya 2013

3
@Soumyaクロスドメインはこのコードとは何の関係もありません。コマンドでバイパスするセキュリティの問題があります。
アリストス2013

9
@Soumyaを探して、X-FRAME-OPTIONS行を追加します。Response.AddHeader("X-FRAME-OPTIONS", "SAMEORIGIN");またはresponse.addHeader("X-FRAME-OPTIONS", "Allow-From https://some.othersite.com");
Aristos

15
これにより、クロスドメインのiframeサイジングの問題github.com/davidjbradshaw/iframe-resizer
David Bradshaw

2
@deebsに変更iFrameID.height = "";してみることもできiFrameID.height = "20px";ます。デフォルトのブラウザのiframeの高さは150pxで、これに""リセットされます。
philfreo

112

アリストスへの少し改善された答え...

<script type="text/javascript">
  function resizeIframe(iframe) {
    iframe.height = iframe.contentWindow.document.body.scrollHeight + "px";
  }
</script>  

次に、iframeで次のように宣言します。

<iframe onload="resizeIframe(this)" ...

2つのマイナーな改善があります。

  1. document.getElementByIdを介して要素を取得する必要はありません-onloadコールバックにすでにあるためです。
  2. iframe.height = ""次のステートメントで再割り当てする場合は、を設定する必要はありません。これを行うと、DOM要素を処理するときにオーバーヘッドが発生します。

編集:フレームのコンテンツが常に変化している場合は、次を呼び出します:

parent.resizeIframe(this.frameElement); 

更新後のiframe内から。同じ起源のために働きます。

または自動検出するには:

  // on resize
  this.container = this.frameElement.contentWindow.document.body;

  this.watch = () => {
    cancelAnimationFrame(this.watcher);

    if (this.lastScrollHeight !== container.scrollHeight) {
      parent.resizeIframeToContentSize(this.frameElement);  
    }
    this.lastScrollHeight = container.scrollHeight;
    this.watcher = requestAnimationFrame(this.watch);
  };
  this.watcher = window.requestAnimationFrame(this.watch);

6
フレームのコンテンツが常に変化している場合はどうしますか?
ケビン

コンテンツサイズが変化し続ける場合や、iframeがページを取得するドメイン以外のドメインに配置されるように設計されている場合は、別の方法を実行する必要があります。
BlueFish 2013年

4
このための解決策は、postMessageとreceiveMessageを使用することです。私はgithub.com/jeffomatic/nojquery-postmessage
BlueFish

新しい高さを計算し、メッセージを受信する必要がある親フレームにメッセージを送信し、それに応じてiframeの高さを調整するという考え方です。
BlueFish 2013年

私にとっては常にいくつかのピクセルが短かったので、これを思いつきました: function resizeIframe(iframe) { var size=iframe.contentWindow.document.body.scrollHeight; var size_new=size+20; iframe.height = size_new + "px"; }
MartinMühl

56

X-FRAME-OPTIONS:Allow-From はsafariまたはchromeでサポートされていないため、受け入れられた回答では不十分であることがわかりました。代わりに、プレゼンテーションで見つかった別のアプローチで行った DisqusのBen Vinegarによる。イベントリスナーを親ウィンドウに追加し、iframe内でwindow.postMessageを使用してイベントを親に送信して、何かをするように指示します(iframeのサイズを変更する)。

親ドキュメントにイベントリスナーを追加します。

window.addEventListener('message', function(e) {
  var $iframe = jQuery("#myIframe");
  var eventName = e.data[0];
  var data = e.data[1];
  switch(eventName) {
    case 'setHeight':
      $iframe.height(data);
      break;
  }
}, false);

そして、iframe内に、メッセージを投稿する関数を記述します。

function resize() {
  var height = document.getElementsByTagName("html")[0].scrollHeight;
  window.parent.postMessage(["setHeight", height], "*"); 
}

最後に、iframe内で、onLoadをbodyタグに追加して、サイズ変更関数を起動します。

<body onLoad="resize();">

1
これが機能するためには、「window.parent」を「parent」に変更する必要がありました。
プログラハンマー2014

すごい!しかし、それは高さを一度だけロードします。:あなたはIFRAMEが本当に応答したい場合は、私はこのように、毎秒リサイズメソッドを呼び出すことを好むsetInterval(resize, 1000);
ジュール・コッレ

12

これをiframeに追加します。これは私にとってはうまくいきました:

onload="this.height=this.contentWindow.document.body.scrollHeight;"

そして、jQueryを使用する場合は、次のコードを試してください。

onload="$(this).height($(this.contentWindow.document.body).find(\'div\').first().height());"

6

iFrameのコンテンツの高さを取得するために確認できる4つの異なるプロパティがあります。

document.documentElement.scrollHeight
document.documentElement.offsetHeight
document.body.scrollHeight
document.body.offsetHeight

悲しいことに、彼らはすべて異なる答えを出すことができ、これらはブラウザ間で一貫していません。ボディマージンを0に設定するとdocument.body.offsetHeight、最良の答えが得られます。正しい値を取得するには、この関数を試してください。これは、コンテンツが変更されたとき、またはブラウザのサイズが変更されたときに、iFrameを正しいサイズに維持することも管理するiframe-resizerライブラリから取得されます。

function getIFrameHeight(){
    function getComputedBodyStyle(prop) {
        function getPixelValue(value) {
            var PIXEL = /^\d+(px)?$/i;

            if (PIXEL.test(value)) {
                return parseInt(value,base);
            }

            var 
                style = el.style.left,
                runtimeStyle = el.runtimeStyle.left;

            el.runtimeStyle.left = el.currentStyle.left;
            el.style.left = value || 0;
            value = el.style.pixelLeft;
            el.style.left = style;
            el.runtimeStyle.left = runtimeStyle;

            return value;
        }

        var 
            el = document.body,
            retVal = 0;

        if (document.defaultView && document.defaultView.getComputedStyle) {
            retVal =  document.defaultView.getComputedStyle(el, null)[prop];
        } else {//IE8 & below
            retVal =  getPixelValue(el.currentStyle[prop]);
        } 

        return parseInt(retVal,10);
    }

    return document.body.offsetHeight +
        getComputedBodyStyle('marginTop') +
        getComputedBodyStyle('marginBottom');
}

これは、データテーブルやフローティングdivなどの「ロールアップ」するアイテムでは機能しません。高さは、最終的な高さではなく、通常の巻き上げられた高さに基づいています。
djack109

@ djack109 CSSの何かがページの要素の縮小を停止する可能性が最も高い
David Bradshaw

3

他の回答がうまくいかなかったので、いくつか変更しました。これが役に立てば幸い

$('#iframe').on("load", function() {
    var iframe = $(window.top.document).find("#iframe");
    iframe.height(iframe[0].ownerDocument.body.scrollHeight+'px' );
});

2

javscript / jqueryを使用するのではなく、私が見つけた最も簡単な方法は次のとおりです。

<iframe style="min-height:98vh" src="http://yourdomain.com" width="100%"></iframe>

ここで1vh =ブラウザウィンドウの高さの1%。したがって、設定される高さの理論値は100vhですが、実際には98vhが魔法をかけました。


9
これは、iframeのコンテンツの高さを考慮していません。
エイドリアンポーリー

クロスドメインドラマを回避する簡単な方法がない場合、これは十分に近づきます...
dsghi

2

万が一これが誰かを助けるために。これを機能させるために髪を引っ張っていたところ、iframeに高さ100%のクラスエントリがあることに気付きました。これを削除すると、すべてが期待どおりに機能しました。したがって、CSSの競合がないか確認してください。


2

また、ブラウザがレイアウトを描画する前に常に呼び出されるresizeIframeにrequestAnimationFrameを追加して(たとえば@BlueFishの回答から)、コンテンツの高さが変更されたときにiframeの高さを更新することもできます。たとえば、入力フォーム、遅延ロードされたコンテンツなど。

<script type="text/javascript">
  function resizeIframe(iframe) {
    iframe.height = iframe.contentWindow.document.body.scrollHeight + "px";
    window.requestAnimationFrame(() => resizeIframe(iframe));
  }
</script>  

<iframe onload="resizeIframe(this)" ...

コールバックは、全体的なパフォーマンスに大きな影響を与えないほど高速でなければなりません


1
これは非常に洗練されたソリューションであり、最初のテストから非常にうまく機能します。これを使用することによるパフォーマンスへの影響に興味があります。
KFE

念のために走ったUncaught TypeError: Cannot read property 'scrollHeight' of nullので、bodyあるnullしかし、それは通常動作します。
caot


1

私はjQueryと以下のコードを使用していますが、

var iframe = $(window.top.document).find("#iframe_id_here");
iframe.height(iframe.contents().height()+'px' );

0

トロイからの答えがうまくいかないことがわかりました。これはajaxのために作り直された同じコードです:

$.ajax({                                      
    url: 'data.php',    
    dataType: 'json',                             

    success: function(data)
    {
        // Put the data onto the page

        // Resize the iframe
        var iframe = $(window.top.document).find("#iframe");
        iframe.height( iframe[0].contentDocument.body.scrollHeight+'px' );
    }
});

0

特にスクロールしていないときに、下部で途切れているように見えるウィンドウのチャンクに追加するには、以下を使用しました。

function resizeIframe(iframe) {
    var addHeight = 20; //or whatever size is being cut off
    iframe.height = iframe.contentWindow.document.body.scrollHeight + addHeight + "px";
  }

0

これは、jqueryを使用しないソリューションが必要な場合に役立ちます。その場合は、コンテナを追加して、パディングをパーセンテージで設定する必要があります

HTMLコード例:

<div class="iframecontainer">
    <iframe scrolling="no" src="..." class="iframeclass"width="999px" height="618px"></iframe>
</div>

CSSサンプルコード:

.iframeclass{
    position: absolute;
    top: 0;
    width: 100%;
}

.iframecontainer{
    position: relative;
    width: 100%;
    height: auto;
    padding-top: 61%;
}

0

簡単な解決策は、コンテンツ領域の幅と高さを測定し、それらの測定値を使用して下部パディングの割合を計算することです。

この場合、測定値は1680 x 720 pxなので、下部のパディングは720/1680 = 0.43 * 100で、43%になります。

.canvas-container {    
    position: relative;
    padding-bottom: 43%; // (720 ÷ 1680 = 0.4286 = 43%)
    height: 0;
    overflow: hidden;   
}

.canvas-container iframe {    
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;   
}

0

BlueFishに対する少し改善された答え...

function resizeIframe(iframe) {
    var padding = 50;
    if (iframe.contentWindow.document.body.scrollHeight < (window.innerHeight - padding))
        iframe.height = iframe.contentWindow.document.body.scrollHeight + "px";
    else
        iframe.height = (window.innerHeight - padding) + "px";
}

これは、非常に高さのあるレスポンシブデザインやiframeに適したWindows画面(ブラウザー、電話)の高さを考慮しています。パディングは、画面全体に行き渡る場合に、iframeの上下に必要なパディングを表します。


0
jQuery('.home_vidio_img1 img').click(function(){
    video = '<iframe src="'+ jQuery(this).attr('data-video') +'"></iframe>';
    jQuery(this).replaceWith(video);
});

jQuery('.home_vidio_img2 img').click(function(){
    video = <iframe src="'+ jQuery(this).attr('data-video') +'"></iframe>;
    jQuery('.home_vidio_img1 img').replaceWith(video);
    jQuery('.home_vidio_img1 iframe').replaceWith(video);
});

jQuery('.home_vidio_img3 img').click(function(){
    video = '<iframe src="'+ jQuery(this).attr('data-video') +'"></iframe>';
    jQuery('.home_vidio_img1 img').replaceWith(video);
    jQuery('.home_vidio_img1 iframe').replaceWith(video);
});

jQuery('.home_vidio_img4 img').click(function(){
    video = '<iframe src="'+ jQuery(this).attr('data-video') +'"></iframe>';
    jQuery('.home_vidio_img1 img').replaceWith(video);
    jQuery('.home_vidio_img1 iframe').replaceWith(video);
});

0

PHP htmlspecialchars()を使用したサンプル+高さが存在し、0より大きいかどうかを確認します。

$my_html_markup = ''; // Insert here HTML markup with CSS, JS... '<html><head></head><body>...</body></html>'
$iframe = '<iframe onload="if(this.contentWindow.document.body.scrollHeight) {this.height = this.contentWindow.document.body.scrollHeight;}" width="100%" src="javascript: \''. htmlspecialchars($my_html_markup) . '\'"></iframe>';

0

iframeコンテナーの位置を作成するだけです:絶対とiframeはその内容に応じて高さを自動的に変更します

<style>
   .iframe-container {
       display: block;
       position: absolute;
       /*change position as you need*/
       bottom: 0;
       left: 0;
       right: 0;
       top: 0;
   }
   iframe {
       margin: 0;
       padding: 0;
       border: 0;
       width: 100%;
       background-color: #fff;
   }
 </style>
 <div class="iframe-container">
     <iframe src="http://iframesourcepage"></iframe>
 </div>

-1
$(document).height() // - $('body').offset().top

および/または

$(window).height()

スタックオーバーフローの質問「body要素の高さを取得する方法」を参照してください。

これを試して、jQueryで本体の高さを見つけます。

if $("body").height()

Firebugの場合、値はありません。おそらくそれが問題です。


私は両方を試してみました...それはまだFirefoxで起こります。firefoxはどういうわけかiframeでwindow.height()を取得しません。先ほど触れたように、スクリプトはiframeコンテンツに添付されており、document.ready()関数で呼び出しています
karry
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.