Измените высоту iframe в соответствии с высотой содержимого в нем - PullRequest
69 голосов
/ 08 февраля 2009

Я открываю страницу блога на моем сайте. Проблема в том, что я могу дать ширину iframe, но высота должна быть динамической, чтобы в iframe не было полосы прокрутки, и она выглядит как одна страница ...

Я пробовал различные JavaScript-коды для расчета высоты содержимого, но все они дают ошибку отказано в доступе и бесполезны.

<iframe src="http://bagtheplanet.blogspot.com/" name="ifrm" id="ifrm" width="1024px" ></iframe>

Можем ли мы использовать Ajax для вычисления высоты или, может быть, с помощью PHP?

Ответы [ 10 ]

60 голосов
/ 09 февраля 2009

Чтобы ответить непосредственно на два ваших подвопроса: Нет, вы не можете сделать это с помощью Ajax и не можете рассчитать это с помощью PHP.

В прошлом я использовал триггер со страницы iframe в window.onload (НЕ domready, поскольку загрузка изображений может занять некоторое время), чтобы передать высоту тела страницы родителю. .

<body onload='parent.resizeIframe(document.body.scrollHeight)'>

Тогда parent.resizeIframe выглядит так:

function resizeIframe(newHeight)
{
    document.getElementById('blogIframe').style.height = parseInt(newHeight,10) + 10 + 'px';
}

И вуаля, у вас есть надежный изменяющий размер, который срабатывает, когда страница полностью отображается без всяких неприятностей contentdocument против contentWindow суета:)

Конечно, теперь люди сначала увидят ваш iframe на высоте по умолчанию, но это можно легко сделать, сначала спрятав свой iframe и просто показывая изображение «загрузки». Затем, когда включится функция resizeIframe, поместите туда две дополнительные строки, которые будут скрывать загрузочное изображение, и покажите iframe для этого искусственного Ajax-вида.

Конечно, это работает только из одного домена, поэтому вы можете захотеть использовать прокси-скрипт PHP для встраивания этого материала, и, как только вы пойдете туда, вы можете просто вставить RSS-канал вашего блога прямо на ваш сайт с помощью PHP.

8 голосов
/ 08 февраля 2009

Вы можете сделать это с помощью JavaScript.

document.getElementById('foo').height = document.getElementById('foo').contentWindow.document.body.scrollHeight + "px";
4 голосов
/ 08 февраля 2009

Подгонка содержимого IFRAME довольно просто найти в Google . Вот одно решение :

<script type="text/javascript">
    function autoIframe(frameId) {
       try {
          frame = document.getElementById(frameId);
          innerDoc = (frame.contentDocument) ? frame.contentDocument : frame.contentWindow.document;
          objToResize = (frame.style) ? frame.style : frame;
          objToResize.height = innerDoc.body.scrollHeight + 10;
       }
       catch(err) {
          window.status = err.message;
       }
    }
</script>

Это, конечно, не решает проблему междомена, которая у вас возникла ... Настройка document.domain может помочь, если эти сайты находятся в одном месте. Я не думаю, что есть решение, если вы создаете случайные сайты.

2 голосов
/ 02 марта 2010

Вот мое решение проблемы с использованием MooTools, которое работает в Firefox 3.6, Safari 4.0.4 и Internet Explorer 7:

var iframe_container = $('iframe_container_id');
var iframe_style = {
    height: 300,
    width: '100%'
};
if (!Browser.Engine.trident) {
    // IE has hasLayout issues if iframe display is none, so don't use the loading class
    iframe_container.addClass('loading');
    iframe_style.display = 'none';
}
this.iframe = new IFrame({
    frameBorder: 0,
    src: "http://www.youriframeurl.com/",
    styles: iframe_style,
    events: {
        'load': function() {
            var innerDoc = (this.contentDocument) ? this.contentDocument : this.contentWindow.document;
            var h = this.measure(function(){
                return innerDoc.body.scrollHeight;
            });            
            this.setStyles({
                height: h.toInt(),
                display: 'block'
            });
            if (!Browser.Engine.trident) {
                iframe_container.removeClass('loading');
            }
        }
    }
}).inject(iframe_container);

Введите стиль класса loading для отображения графика загрузки Ajax в середине контейнера iframe. Затем для браузеров, отличных от Internet Explorer, он отобразит IFRAME полной высоты после завершения загрузки содержимого и удалит загрузочную графику.

0 голосов
/ 19 июля 2012

Я только что провел большую часть трех дней, борясь с этим. Я работаю над приложением, которое загружает другие приложения в себя, сохраняя при этом фиксированный верхний и нижний колонтитулы. Вот что я придумала. (Я также успешно использовал EasyXDM, но позже вытащил его, чтобы использовать это решение.)

Обязательно запустите этот код ПОСЛЕ ТОГО, КАК <iframe> существует в DOM. Поместите это в страницу, которая тянет в iframe (родитель).

// get the iframe
var theFrame = $("#myIframe");
// set its height to the height of the window minus the combined height of fixed header and footer
theFrame.height(Number($(window).height()) - 80);

function resizeIframe() {
    theFrame.height(Number($(window).height()) - 80);
}

// setup a resize method to fire off resizeIframe.
// use timeout to filter out unnecessary firing.
var TO = false;
$(window).resize(function() {
    if (TO !== false) clearTimeout(TO);
    TO = setTimeout(resizeIframe, 500); //500 is time in miliseconds
});
0 голосов
/ 14 февраля 2012

Попробуйте, вы можете изменить даже тогда, когда вы хотите. В этом примере используется jQuery.

$('#iframe').live('mousemove', function (event) {   
    var theFrame = $(this, parent.document.body);
    this.height($(document.body).height() - 350);           
});
0 голосов
/ 29 ноября 2011

@ Ответ SchizoDuckie очень элегантный и легкий, но из-за недостаточной реализации Webkit для scrollHeight (см. здесь ) не работает в браузерах на основе Webkit (Safari, Chrome, на различных и различных мобильных платформах ).

Чтобы эта базовая идея работала над Webkit вместе с браузерами Gecko и Trident, нужно всего лишь заменить

<body onload='parent.resizeIframe(document.body.scrollHeight)'>

с

<body onload='parent.resizeIframe(document.body.offsetHeight)'>

Пока все находится в одном домене, это работает довольно хорошо.

0 голосов
/ 06 июля 2010

Хитрость заключается в том, чтобы получить все необходимые события iframe из внешнего скрипта. Например, у вас есть скрипт, который создает iFrame с использованием document.createElement; в этом же сценарии у вас временно есть доступ к содержимому iFrame.

var dFrame = document.createElement("iframe");
dFrame.src = "http://www.example.com";
// Acquire onload and resize the iframe
dFrame.onload = function()
{
    // Setting the content window's resize function tells us when we've changed the height of the internal document
    // It also only needs to do what onload does, so just have it call onload
    dFrame.contentWindow.onresize = function() { dFrame.onload() };
    dFrame.style.height = dFrame.contentWindow.document.body.scrollHeight + "px";
}
window.onresize = function() {
    dFrame.onload();
}

Это работает, потому что dFrame остается в области действия этих функций, предоставляя вам доступ к внешнему элементу iFrame изнутри рамки, позволяя вам видеть фактическую высоту документа и расширять ее по мере необходимости. Этот пример будет работать в Firefox, но больше нигде; Я мог бы дать вам обходные пути, но вы можете выяснить остальное;)

0 голосов
/ 29 июля 2009

Ниже мой onload обработчик событий.

Я использую IFRAME в диалоговом окне jQuery UI . Различные использования потребуют некоторых корректировок. Похоже, это помогает мне (на данный момент) в Internet Explorer 8 и Firefox 3.5. Может потребоваться дополнительная настройка, но общая идея должна быть ясной.

    function onLoadDialog(frame) {
    try {
        var body = frame.contentDocument.body;
        var $body = $(body);
        var $frame = $(frame);
        var contentDiv = frame.parentNode;
        var $contentDiv = $(contentDiv);

        var savedShow = $contentDiv.dialog('option', 'show');
        var position = $contentDiv.dialog('option', 'position');
        // disable show effect to enable re-positioning (UI bug?)
        $contentDiv.dialog('option', 'show', null);
        // show dialog, otherwise sizing won't work
        $contentDiv.dialog('open');

        // Maximize frame width in order to determine minimal scrollHeight
        $frame.css('width', $contentDiv.dialog('option', 'maxWidth') -
                contentDiv.offsetWidth + frame.offsetWidth);

        var minScrollHeight = body.scrollHeight;
        var maxWidth = body.offsetWidth;
        var minWidth = 0;
        // decrease frame width until scrollHeight starts to grow (wrapping)
        while (Math.abs(maxWidth - minWidth) > 10) {
            var width = minWidth + Math.ceil((maxWidth - minWidth) / 2);
            $body.css('width', width);
            if (body.scrollHeight > minScrollHeight) {
                minWidth = width;
            } else {
                maxWidth = width;
            }
        }
        $frame.css('width', maxWidth);
        // use maximum height to avoid vertical scrollbar (if possible)
        var maxHeight = $contentDiv.dialog('option', 'maxHeight')
        $frame.css('height', maxHeight);
        $body.css('width', '');
        // correct for vertical scrollbar (if necessary)
        while (body.clientWidth < maxWidth) {
            $frame.css('width', maxWidth + (maxWidth - body.clientWidth));
        }

        var minScrollWidth = body.scrollWidth;
        var minHeight = Math.min(minScrollHeight, maxHeight);
        // descrease frame height until scrollWidth decreases (wrapping)
        while (Math.abs(maxHeight - minHeight) > 10) {
            var height = minHeight + Math.ceil((maxHeight - minHeight) / 2);
            $body.css('height', height);
            if (body.scrollWidth < minScrollWidth) {
                minHeight = height;
            } else {
                maxHeight = height;
            }
        }
        $frame.css('height', maxHeight);
        $body.css('height', '');

        // reset widths to 'auto' where possible
        $contentDiv.css('width', 'auto');
        $contentDiv.css('height', 'auto');
        $contentDiv.dialog('option', 'width', 'auto');

        // re-position the dialog
        $contentDiv.dialog('option', 'position', position);

        // hide dialog
        $contentDiv.dialog('close');
        // restore show effect
        $contentDiv.dialog('option', 'show', savedShow);
        // open using show effect
        $contentDiv.dialog('open');
        // remove show effect for consecutive requests
        $contentDiv.dialog('option', 'show', null);

        return;
    }

    //An error is raised if the IFrame domain != its container's domain
    catch (e) {
        window.status = 'Error: ' + e.number + '; ' + e.description;
        alert('Error: ' + e.number + '; ' + e.description);
    }
};
0 голосов
/ 08 февраля 2009

Попробуйте использовать атрибут scrolling=no в теге iframe. Mozilla также имеет свойство CSS overflow-x и overflow-y, с которым вы можете ознакомиться.

Что касается высоты, вы также можете попробовать height=100% на теге iframe.

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