làm cho chiều cao iframe động dựa trên nội dung bên trong- JQUERY / Javascript


202

Tôi đang tải một trang web aspx trong iframe. Nội dung trong Iframe có thể cao hơn chiều cao của iframe. Khung nội tuyến không được có thanh cuộn.

Tôi có một divthẻ trình bao bên trong iframe mà về cơ bản là tất cả nội dung. Tôi đã viết một số jQuery để thực hiện thay đổi kích thước:

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

trong đó TB_windowdiv là trong đó Iframechứa.

body - thẻ body của aspx trong iframe.

Kịch bản này được đính kèm với nội dung iframe. Tôi đang nhận được các TB_windowyếu tố từ trang cha. Mặc dù điều này hoạt động tốt trên Chrome, nhưng TB_window sụp đổ trong Firefox. Tôi thực sự bối rối / lạc lõng về lý do tại sao điều đó xảy ra.


trang ifaspx đó là từ cùng một tên miền?
AlexC

bạn có thể kiểm tra $ ("body"). height () có giá trị trong firefox không?
Michael L Watson

có..cách iframe nằm trong cùng miền với trang container
karry

@MichaelLWatson Có vẻ như cửa sổ đồng hồ lửa có giá trị bằng 0 cho chiều cao cơ thể ... Chrome thực sự có giá trị
karry

Ví dụ về chiều cao tự động của iFrame góc: gitlab.com/reduardo7/angular-iframe-auto-height
Eduardo Cuomo

Câu trả lời:


212

Bạn có thể truy xuất chiều cao của IFRAMEnội dung bằng cách sử dụng: contentWindow.document.body.scrollHeight

Sau khi IFRAMEđược tải, bạn có thể thay đổi chiều cao bằng cách thực hiện như sau:

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

Sau đó, trên IFRAMEthẻ, bạn nối trình xử lý như thế này:

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

Tôi đã có một tình huống trước đây khi tôi cần gọi thêm iframeLoadedtừ IFRAMEchính nó sau khi đệ trình biểu mẫu xảy ra trong đó. Bạn có thể thực hiện điều đó bằng cách thực hiện các thao tác sau trong IFRAMEtập lệnh nội dung của:

parent.iframeLoaded();

153
Nó không hỗ trợ trên Cross Domain.
Soumya

3
@Soumya Tên miền chéo không liên quan gì đến mã này. Có một vấn đề bảo mật mà bạn bỏ qua với một lệnh.
Aristos

9
@Soumya Tìm kiếm X-FRAME-OPTIONSđể thêm một dòng như: Response.AddHeader("X-FRAME-OPTIONS", "SAMEORIGIN");hoặcresponse.addHeader("X-FRAME-OPTIONS", "Allow-From https://some.othersite.com");
Aristos

15
Điều này giải quyết vấn đề kích thước iframe tên miền github.com/davidjbradshaw/iframe-resizer
David Bradshaw

2
@deebs Bạn cũng có thể thử đổi iFrameID.height = "";sang iFrameID.height = "20px";. Chiều cao iframe của trình duyệt mặc định là 150px, là thứ ""đặt lại cho nó.
philfreo

112

Một câu trả lời được cải thiện đôi chút cho Aristos ...

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

Sau đó khai báo trong iframe của bạn như sau:

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

Có hai cải tiến nhỏ:

  1. Bạn không cần phải lấy phần tử qua document.getEuityById - vì bạn đã có nó trong cuộc gọi lại onload.
  2. Không cần thiết lập iframe.height = ""nếu bạn sẽ gán lại nó trong câu lệnh tiếp theo. Làm như vậy thực sự phát sinh chi phí khi bạn đang xử lý một phần tử DOM.

Chỉnh sửa: Nếu nội dung trong khung luôn thay đổi, hãy gọi:

parent.resizeIframe(this.frameElement); 

từ trong iframe sau khi cập nhật. Hoạt động cho cùng một nguồn gốc.

Hoặc để tự động phát hiện:

  // 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
Bạn sẽ làm gì nếu nội dung trong khung luôn thay đổi?
Kevin

Nếu kích thước nội dung tiếp tục thay đổi và / hoặc nếu iframe của bạn được thiết kế để ngồi trên các tên miền khác ngoài miền, iframe sẽ kéo trang từ đó, thì bạn sẽ cần phải làm gì đó khác đi.
BlueFish

4
Đối với điều này ... giải pháp là sử dụng postMessage và receiveMessage. Tôi đã giải quyết vấn đề này bằng github.com/jeffomatic/nojquery-postmessage
BlueFish

Ý tưởng là tính toán chiều cao mới và gửi tin nhắn đến khung chính cần nhận tin nhắn và điều chỉnh chiều cao của iframe tương ứng.
BlueFish

Nó luôn luôn là một số Pixels ngắn đối với tôi, vì vậy tôi đã nghĩ ra điều này: function resizeIframe(iframe) { var size=iframe.contentWindow.document.body.scrollHeight; var size_new=size+20; iframe.height = size_new + "px"; }
Martin Mühl 14/12/13

56

Tôi thấy rằng câu trả lời được chấp nhận không đủ, vì X-FRAME-TÙY CHỌN: Cho phép từ không được hỗ trợ trong safari hoặc chrome . Thay vào đó, đã đi với một cách tiếp cận khác, được tìm thấy trong một bài thuyết trình được đưa ra bởi Ben Vinegar từ Disqus. Ý tưởng là thêm một trình lắng nghe sự kiện vào cửa sổ cha, sau đó bên trong iframe, sử dụng window.postMessage để gửi một sự kiện cho cha mẹ bảo nó làm gì đó (thay đổi kích thước iframe).

Vì vậy, trong tài liệu gốc, thêm một trình nghe sự kiện:

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

Và bên trong iframe, hãy viết một hàm để gửi tin nhắn:

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

Cuối cùng, bên trong iframe, thêm onLoad vào thẻ body để kích hoạt chức năng thay đổi kích thước:

<body onLoad="resize();">

1
Để làm việc này với tôi, tôi đã phải thay đổi "window.parent" thành "cha mẹ".
prograhammer

Tuyệt quá! nhưng nó chỉ tải chiều cao một lần. Nếu bạn muốn làm cho iframe thực sự phản hồi, tôi thích gọi phương thức thay đổi kích thước mỗi giây, như sau:setInterval(resize, 1000);
Jules Colle

12

Thêm cái này vào iframe, cái này hiệu quả với tôi:

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

Và nếu bạn sử dụng jQuery, hãy thử mã này:

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

6

Có bốn thuộc tính khác nhau mà bạn có thể xem để lấy chiều cao của nội dung trong iFrame.

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

Đáng buồn thay, tất cả họ có thể đưa ra câu trả lời khác nhau và những điều này không nhất quán giữa các trình duyệt. Nếu bạn đặt lề cơ thể thành 0 thì document.body.offsetHeightcâu trả lời tốt nhất. Để có được giá trị chính xác, hãy thử chức năng này; được lấy từ thư viện iframe-resizer trông sau khi giữ iFrame đúng kích thước khi nội dung thay đổi hoặc trình duyệt được thay đổi kích thước.

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

Điều này không hoạt động với các mục "cuộn lên", ví dụ như datatables hoặc div div. Chiều cao được dựa trên bất kỳ chiều cao không được kiểm soát bình thường nào và không phải là chiều cao cuối cùng.
djack109

@ djack109 rất có thể là một cái gì đó trong CSS của bạn ngăn chặn một yếu tố thu nhỏ trên trang của bạn
David Bradshaw

3

Các câu trả lời khác không hiệu quả với tôi nên tôi đã thực hiện một số thay đổi. Hy vọng điều này sẽ giúp

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

2

Thay vì sử dụng javscript / jquery, cách dễ nhất tôi tìm thấy là:

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

Ở đây 1vh = 1% chiều cao cửa sổ Trình duyệt. Vì vậy, giá trị lý thuyết của chiều cao được đặt là 100vh nhưng thực tế 98vh đã làm nên điều kỳ diệu.


9
Điều này không tính đến chiều cao nội dung của iframe.
Adrian Pauly

Điều này đủ gần khi bạn không có cách đơn giản để làm việc xung quanh bộ phim truyền hình nhiều tên miền ...
DSghi

2

Chỉ trong trường hợp này giúp bất cứ ai. Tôi đang kéo tóc ra để cố gắng làm việc này, sau đó tôi nhận thấy iframe có mục nhập lớp với chiều cao: 100%. Khi tôi loại bỏ điều này, mọi thứ hoạt động như mong đợi. Vì vậy, xin vui lòng kiểm tra bất kỳ xung đột css.


2

bạn cũng có thể thêm một requestAnimationFrame lặp lại vào resizeIframe của mình (ví dụ từ câu trả lời của @ BlueFish) sẽ luôn được gọi trước khi trình duyệt vẽ bố cục và bạn có thể cập nhật chiều cao của iframe khi nội dung của nó thay đổi độ cao. ví dụ: hình thức đầu vào, nội dung tải lười biếng, vv

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

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

cuộc gọi lại của bạn phải đủ nhanh để không ảnh hưởng lớn đến hiệu suất tổng thể của bạn


1
Đây là một giải pháp rất khéo léo, từ thử nghiệm ban đầu, hoạt động rất tốt. Tôi sẽ quan tâm đến ý nghĩa hiệu suất của việc sử dụng này.
KFE

Chỉ cần chạy vào một trường hợp Uncaught TypeError: Cannot read property 'scrollHeight' of nullkể từ khi bodynull, tuy nhiên nó hoạt động thường.
caot


1

Tôi đang sử dụng jQuery và đoạn mã dưới đây làm việc cho tôi,

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

0

Tôi tìm thấy câu trả lời từ Troy không hoạt động. Đây là cùng một mã được làm lại cho 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

Để thêm vào phần cửa sổ dường như bị cắt ở phía dưới, đặc biệt là khi bạn không cuộn tôi đã sử dụng:

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

0

Điều này rất hữu ích khi bạn yêu cầu một giải pháp không có jquery. Trong trường hợp đó, bạn nên thử thêm một thùng chứa và đặt phần đệm vào nó theo tỷ lệ phần trăm

Mã ví dụ HTML:

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

Mã ví dụ CSS:

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

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

0

Giải pháp đơn giản là đo chiều rộng và chiều cao của khu vực nội dung, sau đó sử dụng các phép đo đó để tính tỷ lệ phần trăm đệm dưới cùng.

Trong trường hợp này, các phép đo là 1680 x 720 px, do đó, phần đệm ở phía dưới là 720/1680 = 0,43 * 100, tỷ lệ này là 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

Một câu trả lời được cải thiện một chút cho 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";
}

Điều này sẽ xem xét chiều cao của màn hình windows (trình duyệt, điện thoại), rất tốt cho thiết kế đáp ứng và iframe có chiều cao rất lớn. Đệm đại diện cho phần đệm bạn muốn ở trên và dưới iframe trong trường hợp nó đi qua toàn màn hình.


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

Mẫu bằng cách sử dụng PHP htmlspecialchars () + kiểm tra xem chiều cao có tồn tại và> 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

chỉ cần tạo vị trí vùng chứa iframe: tuyệt đối và iframe sẽ tự động thay đổi chiều cao theo nội dung của nó

<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

và / hoặc

$(window).height()

Xem câu hỏi Stack Overflow Làm thế nào để có được chiều cao của một phần tử cơ thể .

Hãy thử điều này để tìm chiều cao của cơ thể trong jQuery:

if $("body").height()

Nó không có giá trị nếu Fireorms . Có lẽ đó là vấn đề.


Tôi đã thử làm cả hai ... nó vẫn xảy ra trên Firefox. firefox bằng cách nào đó không nhận được window.height () trên iframe. Như tôi đã đề cập, tập lệnh được đính kèm với nội dung Iframe và tôi đang gọi nó trong hàm
document. Yet
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.