ทำให้ iframe height เป็นไดนามิกตามเนื้อหาภายใน JQUERY / Javascript


202

ฉันกำลังโหลดเว็บเพจ aspx ใน iframe เนื้อหาใน Iframe สามารถมีความสูงได้มากกว่าความสูงของ iframe iframe ไม่ควรมีแถบเลื่อน

ฉันมีdivแท็กwrapper ภายใน iframe ซึ่งโดยทั่วไปคือเนื้อหาทั้งหมด ฉันเขียน jQuery เพื่อให้การปรับขนาดเกิดขึ้น:

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

ที่ไหน TB_windowdiv ในที่ที่Iframeมีอยู่

body - แท็กเนื้อความของ aspx ใน iframe

สคริปต์นี้แนบมากับเนื้อหา iframe ฉันได้รับTB_windowองค์ประกอบจากหน้าหลัก ขณะนี้ใช้งานได้ดีบน Chrome แต่ TB_window ยุบใน Firefox ฉันสับสน / หลงทางในสิ่งที่เกิดขึ้น


เพจ. aspx iframe นั้นมาจากชื่อโดเมนเดียวกันหรือไม่
AlexC

คุณสามารถตรวจสอบ $ ("body"). height () มีค่าเป็น firefox ได้หรือไม่?
Michael L Watson

ใช่ .. iframe อยู่ในโดเมนเดียวกับหน้าคอนเทนเนอร์
karry

@MichaelLWatson ดูเหมือนว่าหน้าต่างวางเพลิงนาฬิกามีค่าเป็น 0 สำหรับความสูงของร่างกาย ... Chrome จะมีค่าแม้ว่า
Karry

ตัวอย่างความสูงอัตโนมัติของ Angular iFrame: gitlab.com/reduardo7/angular-iframe-auto-height
Eduardo Cuomo

คำตอบ:


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()" ...

ฉันมีสถานการณ์อยู่พักหนึ่งแล้วที่ฉันต้องการโทรiframeLoadedจากIFRAMEตัวเองหลังจากที่มีการส่งแบบฟอร์มเกิดขึ้นภายใน คุณสามารถทำได้โดยทำสิ่งต่อไปนี้ภายในIFRAMEสคริปต์เนื้อหาของ:

parent.iframeLoaded();

153
ไม่รองรับ Cross Domain
Soumya

3
@Soumya การข้ามโดเมนไม่มีส่วนเกี่ยวข้องกับรหัสนี้ มีปัญหาด้านความปลอดภัยที่คุณข้ามด้วยคำสั่ง
Aristos

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 height ของเบราว์เซอร์เริ่มต้นคือ 150px ซึ่งเป็นสิ่งที่""รีเซ็ตกลับไปเป็น
philfreo

112

คำตอบที่ดีขึ้นเล็กน้อยสำหรับ Aristos ...

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

จากนั้นให้ประกาศใน iframe ของคุณดังนี้:

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

มีการปรับปรุงเล็กน้อยสองประการ:

  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
คุณจะทำอย่างไรถ้าเนื้อหาในเฟรมเปลี่ยนไปตลอดเวลา?
Kevin

หากขนาดเนื้อหาเปลี่ยนแปลงตลอดเวลาและ / หรือหาก iframe ของคุณได้รับการออกแบบให้นั่งบนโดเมนอื่นนอกเหนือจากโดเมน iframe จะดึงหน้าเว็บจากนั้นคุณจะต้องทำสิ่งที่แตกต่างออกไป
BlueFish

4
สำหรับสิ่งนี้ ... ทางออกคือใช้ postMessage และ receiveMessage ฉันแก้ไขได้โดยใช้github.com/jeffomatic/nojquery-postmessage
BlueFish

แนวคิดคือการคำนวณความสูงใหม่และส่งข้อความไปยังเฟรมหลักซึ่งจำเป็นต้องได้รับข้อความและปรับความสูงของ iframe ตามลำดับ
BlueFish

มันเป็นพิกเซลสั้น ๆ เสมอสำหรับฉันดังนั้นฉันจึงได้สิ่งนี้: function resizeIframe(iframe) { var size=iframe.contentWindow.document.body.scrollHeight; var size_new=size+20; iframe.height = size_new + "px"; }
Martin Mühl

56

ฉันพบว่าคำตอบที่ได้รับการยอมรับไม่ได้พอเพียงตั้งแต่ X-Frame-OPTIONS: อนุญาตจากไม่ได้รับการสนับสนุนในซาฟารีหรือโครเมี่ยม ไปด้วยวิธีการที่แตกต่างกันแทนพบในการนำเสนอที่ได้รับโดย Ben Vinegar จาก Disqus แนวคิดคือการเพิ่มฟังเหตุการณ์ไปยังหน้าต่างหลักและจากนั้นใน 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"
prograhammer

ที่ดี! แต่จะโหลดความสูงเพียงครั้งเดียว หากคุณต้องการทำให้ iframe ตอบสนองอย่างแท้จริงฉันชอบที่จะเรียกวิธีการปรับขนาดทุกวินาทีเช่นนี้:setInterval(resize, 1000);
Jules Colle

12

เพิ่มลงใน iframe นี่ใช้งานได้สำหรับฉัน:

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

และถ้าคุณใช้ jQuery ลองใช้รหัสนี้:

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

6

มีคุณสมบัติที่แตกต่างกันสี่ประการที่คุณสามารถดูเพื่อให้ได้ความสูงของเนื้อหาใน iFrame

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

น่าเศร้าที่พวกเขาทุกคนสามารถให้คำตอบที่แตกต่างกันและสิ่งเหล่านี้ไม่สอดคล้องกันระหว่างเบราว์เซอร์ หากคุณตั้งค่าระยะขอบของร่างกายเป็น 0 ดังนั้นdocument.body.offsetHeightคำตอบที่ให้คำตอบที่ดีที่สุด เพื่อให้ได้ค่าที่ถูกต้องให้ลองใช้ฟังก์ชันนี้ ซึ่งถูกนำมาจากไลบรารีiframe-resizerที่ดูแลหลังจากการรักษาขนาด iFrame ให้ถูกต้องเมื่อเนื้อหาเปลี่ยนแปลงหรือเบราว์เซอร์ถูกปรับขนาด

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

นี่จะเข้าใกล้พอเมื่อคุณไม่มีวิธีง่ายๆในการแก้ปัญหาละครข้ามโดเมน ...
dsghi

2

ในกรณีนี้จะช่วยให้ทุกคน ฉันดึงผมออกมาเพื่อพยายามทำให้มันเป็นจริงจากนั้นฉันสังเกตเห็นว่า iframe มีระดับความสูง: 100% เมื่อฉันลบสิ่งนี้ทุกอย่างทำงานตามที่คาดไว้ ดังนั้นโปรดตรวจสอบความขัดแย้งของ css


2

คุณสามารถเพิ่ม requestAnimationFrame ที่ทำซ้ำไปยัง resizeIframe ของคุณ (เช่นจากคำตอบของ @ 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

คุณสามารถดูคำถามที่เกี่ยวข้องได้ที่นี่ - วิธีทำให้ความกว้างและความสูงของ iframe เหมือนกับ div parent

วิธีตั้งค่าความสูงแบบไดนามิก -

  1. เราจำเป็นต้องสื่อสารกับ iFrames ข้ามโดเมนและผู้ปกครอง
  2. จากนั้นเราสามารถส่งเลื่อนความสูง / ความสูงของเนื้อหาของ iframe ไปที่หน้าต่างหลัก

และรหัส - https://gist.github.com/mohandere/a2e67971858ee2c3999d62e3843889a8


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";
}

สิ่งนี้คำนึงถึงความสูงของหน้าจอ windows (เบราว์เซอร์, โทรศัพท์) ซึ่งเหมาะสำหรับการออกแบบที่ตอบสนองและ iframes ที่มีความสูงมาก Padding แสดงถึงการขยายที่คุณต้องการด้านบนและด้านล่างของ 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()

ดูคำถามกองมากเกินวิธีการได้รับความสูงขององค์ประกอบร่างกาย

ลองใช้วิธีนี้เพื่อค้นหาความสูงของร่างกายใน jQuery:

if $("body").height()

มันไม่ได้มีค่าถ้าFirebug บางทีนั่นอาจเป็นปัญหา


ฉันลองทำทั้งสองอย่าง ... มันยังคงเกิดขึ้นกับ Firefox Firefox อย่างใดไม่ได้รับ window.height () ใน iframe ตามที่ฉันได้กล่าวมาสคริปต์จะถูกแนบไปกับเนื้อหา Iframe และฉันกำลังเรียกมันในฟังก์ชั่น document.ready ()
karry
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.