membuat iframe height dinamis berdasarkan konten di dalam- JQUERY / Javascript


202

Saya memuat halaman web aspx dalam iframe. Konten dalam Iframe bisa lebih tinggi dari tinggi iframe. Iframe seharusnya tidak memiliki bilah gulir.

Saya memiliki divtag pembungkus di dalam iframe yang pada dasarnya adalah semua konten. Saya menulis beberapa jQuery untuk membuat ukurannya terjadi:

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

di mana TB_windowdiv di mana Iframeterkandung.

body - tag body dari aspx di iframe.

Skrip ini dilampirkan ke konten iframe. Saya mendapatkan TB_windowelemen dari halaman induk. Meskipun ini berfungsi dengan baik di Chrome, tetapi TB_window runtuh di Firefox. Saya benar-benar bingung / bingung mengapa itu terjadi.


bahwa halaman iframe .aspx berasal dari nama domain yang sama?
AlexC

dapatkah Anda memeriksa $ ("body"). height () memiliki nilai di firefox?
Michael L Watson

ya .. iframe berada dalam domain yang sama dengan halaman kontainer
karry

@MichaelLWatson Sepertinya jendela arloji firebug memiliki nilai 0 untuk tinggi badan ... Chrome memang memiliki nilai
karry

Contoh iFrame Auto-Height sudut
Eduardo Cuomo

Jawaban:


212

Anda dapat mengambil ketinggian IFRAMEkonten dengan menggunakan: contentWindow.document.body.scrollHeight

Setelah IFRAMEdimuat, Anda dapat mengubah ketinggian dengan melakukan hal berikut:

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

Kemudian, pada IFRAMEtag, Anda menghubungkan pawang seperti ini:

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

Saya memiliki situasi beberapa waktu lalu di mana saya juga perlu menelepon iframeLoadeddari IFRAMEdirinya sendiri setelah pengajuan formulir terjadi di dalam. Anda dapat melakukannya dengan melakukan hal berikut dalam IFRAMEskrip konten:

parent.iframeLoaded();

153
Itu tidak mendukung di Cross Domain.
Soumya

3
@ Soumya Domain silang tidak ada hubungannya dengan kode ini. Ada masalah keamanan yang Anda bypass dengan perintah.
Aristos

9
@ Soumum Carilah untuk X-FRAME-OPTIONSmenambahkan baris sebagai: Response.AddHeader("X-FRAME-OPTIONS", "SAMEORIGIN");atauresponse.addHeader("X-FRAME-OPTIONS", "Allow-From https://some.othersite.com");
Aristos

15
Ini memecahkan masalah ukuran domain iframe github.com/davidjbradshaw/iframe-resizer
David Bradshaw

2
@deebs Anda juga bisa mencoba mengubah iFrameID.height = "";ke iFrameID.height = "20px";. Tinggi iframe browser default adalah 150px yang merupakan pengaturan ""ulang kembali.
philfreo

112

Jawaban yang sedikit lebih baik untuk Aristos ...

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

Kemudian nyatakan dalam iframe Anda sebagai berikut:

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

Ada dua perbaikan kecil:

  1. Anda tidak perlu mendapatkan elemen melalui document.getElementById - karena Anda sudah memilikinya di callback onload.
  2. Tidak perlu mengatur iframe.height = ""apakah Anda akan menetapkan kembali dalam pernyataan berikutnya. Melakukan hal itu sebenarnya menimbulkan overhead saat Anda berurusan dengan elemen DOM.

Sunting: Jika konten dalam bingkai selalu berubah maka panggil:

parent.resizeIframe(this.frameElement); 

dari dalam iframe setelah pembaruan. Bekerja untuk sumber yang sama.

Atau untuk mendeteksi secara otomatis:

  // 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
Apa yang akan Anda lakukan jika konten dalam bingkai selalu berubah?
Kevin

Jika ukuran konten terus berubah dan / atau jika iframe Anda dirancang untuk duduk di domain lain selain domain, iframe menarik halaman dari, maka Anda perlu melakukan sesuatu yang berbeda.
BlueFish

4
Untuk ini ... solusinya adalah menggunakan postMessage dan acceptMessage. Saya memecahkan ini menggunakan github.com/jeffomatic/nojquery-postmessage
BlueFish

Idenya adalah untuk menghitung ketinggian baru dan mengirim pesan ke kerangka induk yang perlu menerima pesan dan menyesuaikan tinggi iframe sesuai.
BlueFish

Selalu ada beberapa Pixel yang singkat untuk saya, jadi saya menghasilkan ini: function resizeIframe(iframe) { var size=iframe.contentWindow.document.body.scrollHeight; var size_new=size+20; iframe.height = size_new + "px"; }
Martin Mühl

56

Saya menemukan bahwa jawaban yang diterima tidak cukup, karena X-FRAME-OPTIONS: Allow-From tidak didukung dalam safari atau chrome . Pergi dengan pendekatan yang berbeda sebagai gantinya, ditemukan dalam presentasi yang diberikan oleh Ben Vinegar dari Disqus. Idenya adalah untuk menambahkan pendengar acara ke jendela induk, dan kemudian di dalam iframe, gunakan window.postMessage untuk mengirim acara ke orang tua yang memberitahu itu untuk melakukan sesuatu (mengubah ukuran iframe).

Jadi di dokumen induk, tambahkan pendengar acara:

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);

Dan di dalam iframe, tulis fungsi untuk memposting pesan:

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

Terakhir, di dalam iframe, tambahkan onLoad ke tag tubuh untuk menjalankan fungsi pengubahan ukuran:

<body onLoad="resize();">

1
Agar ini bekerja untuk saya, saya harus mengubah "window.parent" menjadi "orangtua" saja.
prograhammer

Bagus! tetapi hanya memuat ketinggian sekali. Jika Anda ingin menjadikan iframe benar-benar responsif, saya lebih suka memanggil metode pengubahan ukuran setiap detik, seperti ini:setInterval(resize, 1000);
Jules Colle

12

Tambahkan ini ke iframe, ini bekerja untuk saya:

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

Dan jika Anda menggunakan jQuery coba kode ini:

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

6

Ada empat properti berbeda yang bisa Anda lihat untuk mendapatkan ketinggian konten dalam iFrame.

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

Sayangnya mereka semua dapat memberikan jawaban yang berbeda dan ini tidak sesuai antar browser. Jika Anda mengatur margin tubuh ke 0 maka itu document.body.offsetHeightmemberikan jawaban terbaik. Untuk mendapatkan nilai yang benar, coba fungsi ini; yang diambil dari pustaka iframe-resizer yang juga terlihat setelah menjaga ukuran iFrame yang benar ketika konten berubah, atau browser diubah ukurannya.

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');
}

Ini tidak bekerja dengan item yang "menggulung" misalnya datatables atau div mengambang. Ketinggiannya didasarkan pada apa pun ketinggian normal yang terbuka dan bukan ketinggian akhir.
djack109

@ djack109 kemungkinan besar sesuatu di CSS Anda menghentikan elemen yang menyusut pada halaman Anda
David Bradshaw

3

Jawaban lain tidak berfungsi untuk saya, jadi saya melakukan beberapa perubahan. Semoga ini bisa membantu

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

2

Daripada menggunakan javascript / jquery cara termudah yang saya temukan adalah:

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

Di sini 1vh = 1% dari tinggi jendela Browser. Jadi nilai teoritis tinggi yang akan ditetapkan adalah 100vh tetapi praktis 98vh melakukan keajaiban.


9
Ini tidak memperhitungkan ketinggian konten iframe.
Adrian Pauly

Ini menjadi cukup dekat ketika Anda tidak memiliki cara sederhana untuk mengatasi drama lintas domain ...
dsghi

2

Kalau-kalau ini membantu siapa pun. Saya mencabut rambut saya untuk mencoba ini bekerja, kemudian saya perhatikan bahwa iframe memiliki entri kelas dengan tinggi: 100%. Ketika saya menghapus ini, semuanya berfungsi seperti yang diharapkan. Jadi, harap periksa apakah ada konflik css.


2

Anda juga bisa menambahkan requestAnimationFrame yang berulang ke resizeIframe Anda (mis. dari jawaban @ BlueFish) yang akan selalu dipanggil sebelum browser mengecat tata letak dan Anda dapat memperbarui ketinggian iframe ketika kontennya telah mengubah ketinggiannya. mis. formulir input, konten yang dimuat malas, dll.

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

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

panggilan balik Anda harus cukup cepat sehingga tidak berdampak besar pada kinerja Anda secara keseluruhan


1
ini adalah solusi yang sangat apik yang, dari pengujian awal, bekerja dengan sangat baik. Saya akan tertarik pada implikasi kinerja menggunakan ini.
KFE

Hanya berlari ke sebuah case Uncaught TypeError: Cannot read property 'scrollHeight' of nullkarena bodyini null, namun biasanya berfungsi.
caot


1

Saya menggunakan jQuery dan kode di bawah ini berfungsi untuk saya,

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

0

Saya menemukan jawaban dari Troy tidak berhasil. Ini adalah kode yang sama yang dikerjakan ulang untuk 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

Untuk menambah potongan jendela yang tampaknya terpotong di bagian bawah, terutama ketika Anda tidak memiliki scrolling yang saya gunakan:

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

0

Yang ini berguna ketika Anda membutuhkan solusi tanpa jquery. Dalam hal ini Anda harus mencoba menambahkan wadah dan mengatur padding dalam persentase

Contoh kode HTML:

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

Contoh kode CSS:

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

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

0

Solusi sederhana adalah mengukur lebar dan tinggi area konten, dan kemudian menggunakan pengukuran tersebut untuk menghitung persentase padding bawah.

Dalam hal ini, pengukurannya adalah 1680 x 720 px, jadi bantalan di bagian bawah adalah 720/1680 = 0,43 * 100, yang mencapai 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

Jawaban yang sedikit lebih baik untuk 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";
}

Ini mempertimbangkan ketinggian layar windows (browser, ponsel) yang bagus untuk desain responsif dan iframe yang memiliki tinggi sangat besar. Padding mewakili padding yang Anda inginkan di atas dan di bawah iframe dalam kasus itu berjalan melalui seluruh layar.


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

Contoh menggunakan PHP htmlspecialchars () + periksa apakah tinggi ada dan> 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

cukup buat posisi wadah iframe: absolut dan iframe akan secara otomatis mengubah ketinggiannya sesuai isinya

<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

dan / atau

$(window).height()

Lihat pertanyaan Stack Overflow Cara mendapatkan ketinggian elemen tubuh .

Coba ini untuk menemukan ketinggian tubuh di jQuery:

if $("body").height()

Itu tidak memiliki nilai jika Firebug . Mungkin itu masalahnya.


Saya mencoba melakukan keduanya ... itu masih terjadi di Firefox. firefox entah bagaimana tidak mendapatkan window.height () di iframe. Seperti yang saya sebutkan, skrip dilampirkan ke konten Iframe dan saya menyebutnya dalam fungsi document.ready ()
karry
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.