Как заставить IFrame реагировать на iOS Safari?

Проблема заключается в том, что когда вы должны использовать IFrames для вставки контента на веб-сайт, то в современном веб-мире ожидается, что IFrame также будет реагировать. Теоретически это просто, просто используйте a <iframe width="100%"></iframe> или установите ширину CSS в iframe { width: 100%; }, но на практике это не совсем так просто, но это может быть.

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

Если вы считаете следующий код:

<html>
<head>
    <meta http-equiv="X-UA-Compatible" content="IE=9,10,11" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Iframe Isolation Test</title>

    <style type="text/css" rel="stylesheet">

        #Main {
            padding: 10px;
        }
    </style>
</head>
<body>
    <h1>Iframe Isolation Test 13.17</h1>
    <div id="Main">
        <iframe height="950" width="100%" src="Content.html"></iframe>
    </div>
</body>
</html>

С Content.html:

<html>
<head>
    <meta http-equiv="X-UA-Compatible" content="IE=9,10,11" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Iframe Isolation Test - Content</title>

    <style type="text/css" rel="stylesheet">

        #Main {
            width: 100%;
            background: #ccc;
        }

    </style>
</head>
<body>
    <div id="Main">
        <div id="ScrolledArea">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc malesuada purus quis commodo convallis. Fusce consectetur mauris eget purus tristique blandit. Nam nec volutpat augue. Aliquam sit amet augue vitae orci fermentum tempor sit amet gravida augue. Pellentesque convallis velit eu malesuada malesuada. Aliquam erat volutpat. Nam sollicitudin nulla nec neque viverra, non suscipit purus tincidunt. Aenean blandit nisi felis, sit amet ornare mi vestibulum ac. Praesent ultrices varius arcu quis fringilla. In vitae dui consequat, rutrum sapien ut, aliquam metus. Proin sit amet porta velit, suscipit dignissim arcu. Cras bibendum tellus eu facilisis sodales. Vestibulum posuere, magna ut iaculis consequat, tortor erat vulputate diam, ut pharetra sapien massa ut magna. Donec massa purus, pharetra sed pellentesque nec, posuere ut velit. Nam venenatis feugiat odio quis tristique. 
        </div>      
    </div>
</body>
</html>

Тогда это работает без проблем в iOS 7.1 Safari. Вы можете менять ландшафт и портрет без каких-либо проблем.

enter image description hereenter image description here

Однако просто изменив CSS Content.html, добавив следующее:

    #ScrolledArea {
        width: 100%;
        overflow: scroll;
        white-space: nowrap;
        background: #ff0000;
    }

Вы получаете следующее:

enter image description hereenter image description here

Как вы можете видеть, хотя контент Content.html полностью реагирует (у div # ScrolledArea есть overflow: scroll set), а ширина iframe равна 100%, iframe по-прежнему принимает полную ширину div # ScrolledArea, как если бы переполнение даже не существует. Демо

В таких случаях, если содержание iframe содержало прокрутки на нем, возникает вопрос, как получить ответ iframe, когда содержимое iframe имеет горизонтальные области прокрутки? Проблема здесь заключается не в том, что Content.html не реагирует, а в том, что iOS Safari просто изменяет размер iframe, так что div#ScrolledArea будет полностью видимым.

Ответ 1

Решение этой проблемы на самом деле довольно простое, и есть два способа сделать это. Если у вас есть контроль над Content.html, просто измените CSS div#ScrolledArea width:

        width: 1px;
        min-width: 100%;
        *width: 100%;

В принципе идея здесь проста: вы устанавливаете width на то, что меньше, чем область просмотра (в этом случае ширина iframe), а затем перезаписывайте ее с помощью min-width: 100%, чтобы разрешить фактическое width: 100%, которое iOS Safari default перезаписывает. *width: 100%; существует, поэтому код останется совместимым с IE6, но если вы не заботитесь о IE6, вы можете его опустить. Демо

enter image description hereenter image description here

Как вы теперь видите, ширина div#ScrolledArea фактически равна 100%, а overflow: scroll; может делать это и скрывать переполняющий контент. Если у вас есть доступ к содержимому iframe, это предпочтительнее.

Однако, если у вас нет доступа к содержимому iframe (по какой-либо причине), вы можете фактически использовать тот же метод для самого iframe. Просто используйте тот же CSS на iframe:

    iframe {
        width: 1px;
        min-width: 100%;
        *width: 100%;
    }

Однако для этого есть одно ограничение: вам нужно отключить полосы прокрутки с помощью scrolling="no" в iframe для этого:

<iframe height="950" width="100%" scrolling="no" src="Content.html"></iframe>

Если полосы прокрутки разрешены, то это больше не будет работать в iframe. Тем не менее, если вы измените Content.html вместо этого, вы можете сохранить прокрутку в iframe. Демо

Ответ 2

Проблема, похоже, в том, что Mobile Safari откажется подчиняться ширине вашего iFrame, если содержащийся в нем документ шире, чем вы указали. Пример:

http://jsbin.com/hapituto/1

В настольном браузере вы увидите iFrame и Div, оба установлены на 300 пикселей. Содержимое более широкое, поэтому вы можете прокручивать iFrame.

В мобильном сафари, однако, вы заметите, что iFrame автоматически расширяется до ширины содержимого.

Я предполагаю, что это обходное решение для давних проблем с прокруткой содержимого внутри страницы. Раньше, если у вас был большой прокручиваемый iframe на сенсорном устройстве, вы бы "застряли" в iframe, поскольку это будет прокрутка вместо самой страницы. Похоже, Apple решила, что поведение iFrame по умолчанию - "нет прокрутки" и расширяется, чтобы предотвратить его.

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

пример: http://jsbin.com/zakedaja/1

Пример разметки:

<div style="overflow: scroll; -webkit-overflow-scrolling: touch; width: 300px;">
   <iframe src="http://jsbin.com/roredora/1/" style="width: 600px;"></iframe>
</div>

В мобильном сафари теперь вы можете прокручивать содержимое полностью расширенного iFrame через div, который его содержит.

Улов: Это выглядит действительно уродливым в настольном браузере, так как теперь у вас двойные полосы прокрутки. Таким образом, вам может потребоваться некоторое обнаружение браузера с JS, чтобы обойти это.

Ответ 3

Мне нужно кросс-браузерное решение. Требования были:

  • нужно работать как на iOS, так и в других местах
  • не имеют доступа к контенту в iFrame
  • это нужно для прокрутки!

Основываясь на том, что я узнал от @Idra относительно прокрутки = "нет" на iOS, и на этом посте о том, как разместить контент iFrame на экране в iOS, я получил вот что. Надеюсь, это поможет кому-то =)

HTML

<div id="url-wrapper"></div>

CSS

html, body{
    height: 100%;
}

#url-wrapper{
    margin-top: 51px;
    height: 100%;
}

#url-wrapper iframe{
    height: 100%;
    width: 100%;
}

#url-wrapper.ios{
    overflow-y: auto;
    -webkit-overflow-scrolling:touch !important;
    height: 100%;
}

#url-wrapper.ios iframe{
    height: 100%;
    min-width: 100%;
    width: 100px;
    *width: 100%;
}

JS

function create_iframe(url){

    var wrapper = jQuery('#url-wrapper');

    if(navigator.userAgent.match(/(iPod|iPhone|iPad)/)){
        wrapper.addClass('ios');
        var scrolling = 'no';
    }else{
        var scrolling = 'yes';
    }

    jQuery('<iframe>', {
        src: url,
        id:  'url',
        frameborder: 0,
        scrolling: scrolling
    }).appendTo(wrapper);

}

Ответ 4

Проблема всех этих решений заключается в том, что высота iframe никогда не меняется.

Это означает, что вы не сможете центрировать элементы внутри iframe используя Javascript, position:fixed; или position:absolute; так как сам iframe никогда не прокручивается.

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

#wrap {
    position: fixed;
    top: 0;
    right:0;
    bottom:0;
    left: 0;
    overflow-y: scroll;
    -webkit-overflow-scrolling: touch;
}

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

Вы можете увидеть быстрое и грязное демо здесь.

Ответ 5

Эта проблема также присутствует в iOS Chrome.

Я просмотрел все приведенные выше решения, большинство из них очень хакерские.

Если вам не нужна поддержка старых браузеров, просто установите ширину iframe равной 100vw;

iframe {
  max-width: 100%; /* Limits width to 100% of container */
  width: 100vw; /* Sets width to 100% of the viewport width while respecting the max-width above */
}

Примечание. Проверьте поддержку единиц просмотраhttps://caniuse.com/#feat=viewport-units

Ответ 6

Я работаю с ionic2, а системная конфигурация - ниже


******************************************************

Your system information:

Cordova CLI: 6.4.0 
Ionic Framework Version: 2.0.0-beta.10
Ionic CLI Version: 2.1.8
Ionic App Lib Version: 2.1.4
ios-deploy version: Not installed
ios-sim version: 5.0.8 
OS: OS X Yosemite
Node Version: v6.2.2
Xcode version: Xcode 7.2 Build version 7C68



******************************************************

Для меня эта проблема решена с помощью этого кода. для тега html iframe -

<div class="iframe_container">
      <iframe class= "animated fadeInUp" id="iframe1" [src]='page' frameborder="0" >
        <!--  <img src="img/video-icon.png"> -->
      </iframe><br>
   </div>

См. css того же самого, что и


.iframe_container {
  overflow: auto; 
  position: relative; 
  -webkit-overflow-scrolling: touch;
  height: 75%;
}

iframe {
  position:relative;
  top: 2%;
  left: 5%;
  border: 0 !important;
  width: 90%;
}

Свойство позиции играет важную роль здесь, в моем случае.
положение: относительная;

Это тоже может помочь!!!

Ответ 7

Только CSS-решение

HTML

<div class="container">
    <div class="h_iframe">
        <iframe  src="//www.youtube.com/embed/9KunP3sZyI0" frameborder="0" allowfullscreen></iframe>
    </div>
</div>

CSS

html,body {
    height:100%;
}
.h_iframe iframe {
    position:absolute;
    top:0;
    left:0;
    width:100%;
    height:100%;
}

DEMO

Еще одна демонстрация здесь с HTML-страницей в iframe

Ответ 8

У меня была проблема с шириной на панели содержимого, которая создавала горизонтальную полосу прокрутки для iframe. Оказалось, что изображение имеет ширину шире, чем ожидалось. Я смог решить это, установив все изображения css max-width на процент.

<meta name="viewport" content="width=device-width, initial-scale=1" />

img {
        max-width: 100%;
        height:auto;
    }

Ответ 9

на самом деле для меня просто работал в IOS отключение прокрутки

<iframe src="//www.youraddress.com/" scrolling="no"></iframe>

и лечение ОС с помощью скрипта.

Ответ 10

Для меня решения CSS не работали. Но установка ширины программно делает свою работу. При загрузке iframe установите ширину программно:

 $('iframe').width('100%');