Как правильно отображать iFrame в мобильном сафари

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

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

Ответ 1

Да, вы не можете ограничить сам 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.

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

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

Ответ 2

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

С Android все, что вам нужно сделать, это окружить iframe с помощью DIV и установить высоту в div для document.documentElement.clientHeight. IOS, однако, является другим животным. Хотя я еще не пробовал решение Sharon, это похоже на хорошее решение. Я нашел более простое решение, но оно работает только с 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 сильно загружены в память, вы можете получить прокрутку прокрутки, для которой вам может понадобиться использовать решение Sharon.

Ответ 3

Это работает, только если вы контролируете внешнюю страницу и страницу 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 в прокручиваемую node.

Ответ 4

Я поставил код @Sharon вместе в следующее, которое работает для меня на 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>

Ответ 5

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

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

Спасибо!

Ответ 6

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

if ('ontouchstart' in document.documentElement)
     {
        document.getElementById('Scrolling').src = document.getElementById('SCrolling').src;
    }

Ответ 7

Я реализовал следующее, и он работает хорошо. В основном, я устанавливал размеры тела в соответствии с размером содержимого iFrame. Это означает, что наше меню без iFrame можно прокручивать с экрана, но в остальном это делает наши сайты функциональными с iPad и iPhone. "рабочая область" - это идентификатор нашего 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';
     });
}

Ответ 8

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

Что это.

Ответ 9

Чисто используя код MSchimpf и Ahmad, я сделал настройки, поэтому я мог бы иметь 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 -->   

Ответ 10

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

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