зробіть висоту iframe динамічною на основі вмісту всередині- JQUERY / Javascript


202

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

У мене є divтег обгортки всередині iframe, який в основному є усім вмістом. Я написав jQuery, щоб змінити розмір:

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

де TB_windowє діва, в якій Iframeміститься.

body - тег тіла aspx у iframe.

Цей скрипт додається до вмісту iframe. Я отримую TB_windowелемент з батьківської сторінки. Хоча це добре працює в Chrome, але TB_window в Firefox згортається. Я дуже розгублений / загублений, чому це відбувається.


що .aspx iframe сторінка з того ж доменного імені?
AlexC

чи можете ви перевірити значення $ ("body"). висота () має значення у firefox?
Майкл Л Уотсон

так .. iframe знаходиться в тому самому домені, що і сторінка контейнера
karry

@MichaelLWatson Схоже, що вікно годинника firebug має значення 0 як для росту тіла ... У Chrome має значення, хоча
karry

Приклад автоматичної висоти кутового iFrame: gitlab.com/reduardo7/angular-iframe-auto-height
Едуардо Куомо

Відповіді:


211

Ви можете отримати висоту 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();

152
Він не підтримує Cross Cross.
Сум’я

3
@Soumya Перехресний домен не має нічого спільного з цим кодом. Виникає проблема безпеки, яку ви обходите командою.
Арістос

9
@Soumya Шукайте, X-FRAME-OPTIONSщоб додати рядок як: Response.AddHeader("X-FRAME-OPTIONS", "SAMEORIGIN");абоresponse.addHeader("X-FRAME-OPTIONS", "Allow-From https://some.othersite.com");
Арістос

15
Це вирішує міждоменний iframe розмір випуску github.com/davidjbradshaw/iframe-resizer
Девід Бредшоу

2
@deebs Ви також можете спробувати змінити iFrameID.height = "";до iFrameID.height = "20px";. Висота iframe для браузера за замовчуванням - 150 пікс "".
philfreo

112

Трохи вдосконалена відповідь Арістосу ...

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

Потім заявіть у своєму iframe наступним чином:

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

Є два незначні вдосконалення:

  1. Вам не потрібно отримувати елемент через document.getElementById - як у вас вже є у зворотному звороті при завантаженні.
  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 призначений для розміщення в інших доменах, крім домену, звідки iframe перетягує сторінку, вам потрібно буде зробити щось інше.
BlueFish

4
Для цього ... рішення полягає у використанні постмесеза та прийому. Я вирішив це за допомогою 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"; }
Мартін Мюль

56

Я виявив, що прийнята відповідь недостатня, оскільки X-FRAME-ВАРІАНТИ: Allow-From не підтримується в сафарі чи хромі . Натомість пішов з іншим підходом, знайдений у презентації, яку Бен Оцет з 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" на "батько".
програмамер

Чудово! але він завантажує висоту лише один раз. Якщо ви хочете зробити 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');
}

Це не працює з елементами, які "згортаються", наприклад, з таблицями даних або плаваючими ділами. Висота заснована на тому, якою була б нормальна висота розгортання, а не кінцева висота.
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% від висоти вікна браузера. Таким чином, теоретичне значення висоти, яке потрібно встановити, становить 100Вт, але практично 98 ВГт зробило магію.


9
Це не враховує висоту вмісту iframe.
Адріан Полі

Це стає досить близьким, коли у вас немає простого способу обійти міждоменну драму ...
dsghi

2

Про всяк випадок це допомагає комусь. Я витягнув волосся, намагаючись змусити це працювати, тоді я помітив, що в кадрі є висота в класі: 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, проте він працює зазвичай.
кат

1

Ви можете задати відповідне питання тут - Як зробити ширину та висоту iframe такою ж, як її батьківський div?

Щоб встановити динамічну висоту -

  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

Цей варіант корисний, коли вам потрібне рішення без жодного запиту. У такому випадку слід спробувати додати контейнер і встановити прокладку до нього у відсотках

Приклад 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 (браузер, телефон), що добре підходить для чуйного дизайну та кадрів з величезною висотою. Прокладка являє собою прокладку, яку ви хочете вище і нижче рамки кадрів, якщо вона проходить через весь екран.


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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.