сделать высоту iframe динамической на основе содержимого внутри JQUERY / Javascript - PullRequest
180 голосов
/ 06 февраля 2012

Я загружаю веб-страницу aspx в iframe. Содержимое в Iframe может быть больше высоты, чем высота iframe. В iframe не должно быть полос прокрутки.

У меня есть тег-обертка div внутри iframe, который по сути является всем содержимым. Я написал несколько jQuery для изменения размера:

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

где TB_window - это div, в котором содержится Iframe.

body - тег body aspx в iframe.

Этот скрипт прикреплен к содержимому iframe. Я получаю элемент TB_window с родительской страницы. Хотя это работает нормально на Chrome, но TB_window рушится в Firefox. Я действительно запутался / растерялся из-за того, почему это происходит.

Ответы [ 17 ]

196 голосов
/ 06 февраля 2012

Вы можете получить высоту содержимого 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();
95 голосов
/ 31 января 2013

Немного улучшенный ответ Аристосу ...

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

Затем объявите в своем фрейме следующее:

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

Есть два незначительных улучшения:

  1. Вам не нужно получать элемент через document.getElementById - так как он у вас уже есть в обратном вызове onload.
  2. Нет необходимости устанавливать iframe.height = "", если вы собираетесь переназначить егов самом следующем заявлении.Это на самом деле влечет за собой дополнительные издержки при работе с элементом DOM.
51 голосов
/ 11 апреля 2014

Я обнаружил, что принятого ответа недостаточно, поскольку X-FRAME-OPTIONS: Allow-From не поддерживается в safari или chrome .Вместо этого пошли с другим подходом, который можно найти в презентации , которую дал Бен Винегар из 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();">
10 голосов
/ 22 апреля 2015

Добавьте это в iframe, у меня это сработало:

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

А если вы используете jQuery, попробуйте этот код:

onload="$(this).height($(this.contentWindow.document.body).find(\'div\').first().height());"
6 голосов
/ 22 марта 2014

Существует четыре различных свойства, которые вы можете посмотреть, чтобы получить высоту содержимого в 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');
}
2 голосов
/ 20 сентября 2017

На всякий случай это кому-нибудь поможет.Я вырывал свои волосы, пытаясь заставить это работать, затем я заметил, что у iframe была запись класса с высотой: 100%.Когда я убрал это, все работало как ожидалось.Поэтому, пожалуйста, проверьте наличие конфликтов CSS.

1 голос
/ 01 июня 2019

Другие ответы не работали для меня, поэтому я сделал некоторые изменения.Надеюсь, это поможет

$('#iframe').on("load", function() {
    var iframe = $(window.top.document).find("#iframe");
    iframe.height(iframe[0].ownerDocument.body.scrollHeight+'px' );
});
1 голос
/ 12 августа 2016

Вы можете обратиться к связанному вопросу здесь - Как сделать ширину и высоту iframe такими же, как его родительский div?

Чтобы установить динамическую высоту -

  1. Нам нужно связаться с междоменными iFrames и родительским
  2. Затем мы можем отправить высоту прокрутки / высоту содержимого iframe в родительское окно

И коды - https://gist.github.com/mohandere/a2e67971858ee2c3999d62e3843889a8

0 голосов
/ 04 июля 2013

Я нашел ответ от Трои, не работал.Это тот же код, переработанный для 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 голосов
/ 13 ноября 2018

Вы также можете добавить повторяющийся 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)" ...

Ваш обратный вызов должен быть достаточно быстрым, чтобы не иметь большого влияния на общую производительность

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...