как правильно отображать iFrame в мобильном сафари - PullRequest
53 голосов
/ 11 марта 2011

Я пытаюсь отобразить iframe в своем мобильном веб-приложении, но у меня возникают проблемы с ограничением размера iframe размерами экрана iPhone. Кажется, что атрибуты высоты и ширины элемента iframe не имеют никакого эффекта. Окружить его div удается ограничить, но потом я не могу прокрутить внутри iframe.

Кто-нибудь раньше занимался iframes в мобильном сафари? Есть идеи с чего начать?

Ответы [ 10 ]

20 голосов
/ 19 марта 2011

Да, вы не можете ограничить сам iframe высотой и шириной. Вы должны поставить div вокруг него. Если вы управляете контентом в iframe, вы можете поместить JS в контент iframe, который скажет родителю прокрутить div при получении события касания.

как это:

JS:

setTimeout(function () {
var startY = 0;
var startX = 0;
var b = document.body;
b.addEventListener('touchstart', function (event) {
    parent.window.scrollTo(0, 1);
    startY = event.targetTouches[0].pageY;
    startX = event.targetTouches[0].pageX;
});
b.addEventListener('touchmove', function (event) {
    event.preventDefault();
    var posy = event.targetTouches[0].pageY;
    var h = parent.document.getElementById("scroller");
    var sty = h.scrollTop;

    var posx = event.targetTouches[0].pageX;
    var stx = h.scrollLeft;
    h.scrollTop = sty - (posy - startY);
    h.scrollLeft = stx - (posx - startX);
    startY = posy;
    startX = posx;
});
}, 1000);

HTML:

<div id="scroller" style="height: 400px; width: 100%; overflow: auto;">
<iframe height="100%" id="iframe" scrolling="no" width="100%" id="iframe" src="url" />
</div>

Если вы не контролируете содержимое iframe, вы можете использовать наложение поверх iframe аналогичным образом, но тогда вы не можете взаимодействовать с содержимым iframe, кроме как для его прокрутки - так что вы не можете, для Например, нажмите ссылки в iframe.

Раньше вы могли использовать два пальца для прокрутки внутри фрейма, но это больше не работает.

Обновление: iOS 6 сломал это решение для нас. Я пытался получить новое исправление для него, но пока ничего не помогло. Кроме того, больше невозможно отлаживать javascript на устройстве, так как они представили Remote Web Inspector, который требует использования Mac.

11 голосов
/ 08 июня 2012

Если содержимое iFrame не принадлежит вам, приведенное ниже решение не будет работать.

В Android все, что вам нужно сделать, это окружить iframe с помощью DIV и установить высоту в div на document.documentElement.clientHeight. IOS, однако, другое животное. Хотя я еще не пробовал решение Шарона, оно кажется хорошим решением. Я нашел более простое решение, но оно работает только с IOS 5. +.

Окружите свой элемент iframe с помощью DIV (давайте назовем его скроллер), установите высоту DIV и убедитесь, что новый DIV имеет следующий стиль:

$('#scroller').css({'overflow' : 'auto', '-webkit-overflow-scrolling' : 'touch'});

Это само по себе будет работать, но вы заметите, что в большинстве реализаций содержимое в iframe становится пустым при прокрутке и в основном становится бесполезным. Насколько я понимаю, такое поведение было сообщено Apple как ошибка еще в iOS 5.0. Чтобы обойти эту проблему, найдите элемент body в iframe и добавьте -webkit-transform ',' translate3d (0, 0, 0) примерно так:

$('#contentIframe').contents().find('body').css('-webkit-transform', 'translate3d(0, 0, 0)');

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

10 голосов
/ 16 июля 2014

Это работает, только если вы управляете как внешней страницей, так и страницей iframe.

На внешней странице отключите iframe.

<iframe src="" height=200 scrolling=no></iframe>

На странице iframeДобавьте это.

<!doctype html>
...
<style>
html, body {height:100%; overflow:hidden}
body {overflow:auto; -webkit-overflow-scrolling:touch}
</style>

Это работает, потому что современные браузеры используют html для определения высоты, поэтому мы просто присваиваем ей фиксированную высоту и превращаем body в прокручиваемый узел.

4 голосов
/ 14 декабря 2011

Я собрал код @Saron вместе в следующем, который работает для меня на iPad с прокруткой двумя пальцами.Единственное, что вам нужно изменить, чтобы заставить его работать, это атрибут src в iframe (я использовал документ PDF).

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Pdf Scrolling in mobile Safari</title>
</head>
<body>
<div id="scroller" style="height: 400px; width: 100%; overflow: auto;">
<iframe height="100%" id="iframe" scrolling="no" width="100%" id="iframe" src="data/testdocument.pdf" />
</div>
<script type="text/javascript">
    setTimeout(function () {
        var startY = 0;
        var startX = 0;
        var b = document.body;
        b.addEventListener('touchstart', function (event) {
            parent.window.scrollTo(0, 1);
            startY = event.targetTouches[0].pageY;
            startX = event.targetTouches[0].pageX;
        });
        b.addEventListener('touchmove', function (event) {
            event.preventDefault();
            var posy = event.targetTouches[0].pageY;
            var h = parent.document.getElementById("scroller");
            var sty = h.scrollTop;

            var posx = event.targetTouches[0].pageX;
            var stx = h.scrollLeft;
            h.scrollTop = sty - (posy - startY);
            h.scrollLeft = stx - (posx - startX);
            startY = posy;
            startX = posx;
        });
    }, 1000);
    </script>
</body>
</html>
3 голосов
/ 16 ноября 2014
<div id="scroller" style="height: 400px; width: 100%; overflow: auto;">
<iframe height="100%" id="iframe" scrolling="no" width="100%" src="url" />
</div>

Я создаю свой первый сайт, и это помогло мне заставить это работать для всех сайтов, для которых я использую встроенный iframe.

Спасибо!

1 голос
/ 14 января 2012

Метод Шарона работал для меня, однако, когда идет ссылка в iframe, а затем нажимается кнопка возврата браузера, загружается кэшированная версия страницы и iframe больше не прокручивается.Чтобы преодолеть это, я использовал код для обновления страницы следующим образом:

if ('ontouchstart' in document.documentElement)
     {
        document.getElementById('Scrolling').src = document.getElementById('SCrolling').src;
    }
0 голосов
/ 22 января 2016

Не прокручивайте страницу IFrame или ее содержимое, прокручивайте родительскую страницу. Если вы управляете содержимым IFrame, вы можете использовать библиотеку iframe-resizer , чтобы превратить сам элемент iframe в правильный элемент уровня блока с естественной / правильной / собственной высотой. Кроме того, не пытайтесь расположить (фиксированный, абсолютный) ваш iframe на родительской странице или представить iframe в модальном окне, особенно если оно имеет элементы формы.

Я также подозреваю, что iOS Safari имеет нестандартное поведение, которое увеличивает высоту вашего iframe до его естественной высоты, во многом аналогично тому, как библиотека iframe-resizer подойдет для браузеров настольных компьютеров, которые, по-видимому, отображают реагирующий контент iframe на высоте 0px или 150px. или какой-то другой не полезный по умолчанию Если вам нужно ограничить ширину, попробуйте стиль максимальной ширины внутри фрейма.

0 голосов
/ 02 апреля 2013

Чисто используя MSchimpf и код Ахмада, я внес коррективы, чтобы иметь возможность разместить iframe в div, сохраняя верхний и нижний колонтитулы для кнопки «Назад» и брендинга на своей странице. Обновленный код:

<script type="text/javascript">
    $("#webview").bind('pagebeforeshow', function(event){
        $("#iframe").attr('src',cwebview);
    });

    if (navigator.userAgent.indexOf('iPhone') != -1 || navigator.userAgent.indexOf('iPad') != -1)
    {
        $("#webview-content").css("width","100%");
        $("#webview-content").css("height","100%");
        $("#iframe").load(function (){ // Wait until iFrame content is loaded before checking dimensions of the content
            iframeWidth = $("#iframe").contents().width();
            if (iframeWidth > 400)
               $("#webview-content").css("width",(iframeWidth + 182) + 'px');

            iframeHeight = $("#iframe").contents().height();
            if (iframeHeight>200)
                $("#webview-content").css("height",iframeHeight + 'px');
         });
    }       
</script>  

и HTML

<div class="header" data-role="header" data-position="fixed">
</div>

<div id="webview-content" data-role="content" style="height:380px;">
    <iframe id="iframe"></iframe>   
</div><!-- /content -->

<div class="footer" data-role="footer" data-position="fixed">
</div><!-- /footer -->   
0 голосов
/ 31 августа 2012

Решением является использование Scrolling="no" в iframe.

Вот и все.

0 голосов
/ 15 августа 2012

Я реализовал следующее, и это работает хорошо. По сути, я устанавливаю размеры тела в соответствии с размером содержимого iFrame. Это означает, что наше меню без iFrame можно прокручивать за пределы экрана, но в противном случае это делает наши сайты работоспособными с iPad и iPhone. «workbox» - это идентификатор нашего iFrame.

// Configure for scrolling peculiarities of iPad and iPhone

if (navigator.userAgent.indexOf('iPhone') != -1 || navigator.userAgent.indexOf('iPad') != -1)
{
    document.body.style.width = "100%";
    document.body.style.height = "100%";
    $("#workbox").load(function (){ // Wait until iFrame content is loaded before checking dimensions of the content
        iframeWidth = $("#workbox").contents().width();
        if (iframeWidth > 400)
           document.body.style.width = (iframeWidth + 182) + 'px';

        iframeHeight = $("#workbox").contents().height();
        if (iframeHeight>200)
            document.body.style.height = iframeHeight + 'px';
     });
}
...