Як змусити IFrame реагувати на iOS Safari?


134

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

введіть тут опис зображення введіть тут опис зображення

Однак просто змінивши CSS Content.html , додавши це:

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

Ви отримуєте це:

введіть тут опис зображення введіть тут опис зображення

Як ви можете бачити, навіть не дивлячись на те, content.html вмісту повністю реагує ( Div # ScrolledArea має overflow: scrollбезліч) і IFRAME ширина 100% , то IFrame все ще займає всю ширину сну # ScrolledArea як ніби переповнення навіть не існує. Демо

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


Чи можете ви поділитися посиланням з нами? Ви хочете сказати, що iOS розширить iFrame на повну ширину сторінки, якщо сторінка всередині має вміст зі white-space: nowrapстилем?
DA.

@DA Я додав демонстрації як до проблеми, так і до рішення. І ні, саме white-space: nowrapпо собі це не проблема. Я просто використовую його для отримання надзвичайної ширини div#ScrolledArea. Проблема виникає, коли вміст IFrame має в ньому горизонтально прокручувані ділянки. У такому випадку iOS Safari просто ігнорує ваші налаштування ширини і показує вміст отворів і порушує чутливість сайту.
Ідра

Хм ... мені цікаво, чи це "особливість". Було б незручно мати прокручувану область (iFrame), яка містить вміст, що прокручується. Взаємодіяти з сенсорним екраном було б дуже важко.
DA.

@DA Звичайно, це справа племінниці, і те, що ви сказали, може бути правдою (залежить від впровадження, працює для нас), і більшість сайтів не мають горизонтально прокручуваних областей, але коли ви це робите, ви навіть не можете собі уявити скільки часу я витратив на це. Але це може бути проблемою, навіть якщо у вас є зображення, які приховані та прокручені кнопками чи щось подібне.
Ідра

Схоже, що з цим пов'язані питання: stackoverflow.com/questions/5267996/… Це, мабуть, є "функцією" мобільного сафарі ... він намагається забезпечити розмір вмісту таким чином, щоб користувач міг все ще з нею взаємодіють. Я не впевнений, що станеться, якщо у вас є прокрутка вмісту в iframe прокрутки ... як би Safari інтерпретував прогортання вкладених елементів прокрутки?
DA.

Відповіді:


289

Рішення цієї проблеми насправді досить просте, і існує два шляхи вирішити цю проблему. Якщо у вас є контроль над Content.html, просто змініть div#ScrolledAreaCSS ширини на:

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

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

введіть тут опис зображення введіть тут опис зображення

Як ви бачите зараз, 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. Демо


1
Як згадував @NickGottlieb, мені довелося додати !importantдо widthатрибуту, щоб підготувати веб-дизайн iframe, що реагує на iPhone 4 з iOS 7
malisokan

@ ЮнгвиртТони Це не повинно бути необхідним для вирішення проблеми, можливо, що widthбуло встановлено раніше, !importantабо CSS з вищим пріоритетом його перезаписав. В поодиноких випадках в iPhone 4 iOS7 вона не потрібна.
Ідра

Мені теж не потрібно! Чудово працює і на iOS 8. Ура
Сем Потс

Мені потрібно прокручування = не тільки при необхідності, інакше прокрутка = так. То що мені слід виявити? Це проблема iOS? чи проблема з веб-кайтом? чи ...?
Гербз

@ggwarpig - це проблема iOS, де iOS Safari автоматично вмикає атрибут безшовної дії, і ви не можете його перезаписати. Якщо у вас є контроль над вмістом, вам потрібно змінити вміст, щоб scrolling="yes"інакше не було можливості це виправити, щоб виправити роботу на IFRAME потрібно лише scrolling="no"в IFRAME
Ідра,

24

Схоже, проблема полягає в тому, що 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, щоб обійти це.


1
Я все ще стверджую, що це дійсно не в обсягах питання, тому що рішення, яке ви показали тут, є стандартним способом підробити дірку iframe прокрутки в iOS Safari, але врахування цієї проблеми iOS є проблемою щодо прокрутки IFrame (вміст чи іншим чином), тоді приємно мати його тут.
Ідра

1
Я думаю, я не повністю розумію ваше питання. Як я розумію, проблема, яка виникає у вас, полягає в тому, що в iOS Mobile Safari намагається в першу чергу не допустити прокрутки iFrame і примушує її ширину. Я нерозумію вашу проблему?
DA.

По суті, в чому полягає проблема, її необхідне рішення є різне. У початковій проблемі вміст IFrame відповідав, маючи горизонтальний прокручування вмісту, тому питання полягало не в тому, як емулювати прокрутку iframe , а в тому, як отримати ширину iframe на 100%, тобто відповідати, тоді як у вас горизонтально прокручується вміст з що рамка Ось чому вищезазначений підхід не працює в цьому випадку, оскільки розроблена чутливість була порушена і вам потрібно прокручуватись, щоб побачити повний вміст, навіть у місцях, які були дизайном, як правило, не потрібно.
Ідра

1
Прошу вибачення, я зрозумів, що ввів вас в оману в одному з коментарів. Iframe не прокручується. Це був сенс, iframe не повинен був прокручувати лише частини його вмісту, тобто div#ScrolledArea(зеленим кольором) у моєму прикладі. Я просто перечитав раніше. Але рамка iframe не повинна прокручуватися лише змінюючи розміри на основі елемента контейнера, тобто матиwidth: 100%;
Ідра,

18

Мені потрібно було крос-браузерне рішення. Вимоги були:

  • необхідні для роботи як на 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);

}

1
прихильне, але ... чому правило IE6 у класі "ios"? :-)
Дж. Бруні

12

Проблема всіх цих рішень полягає в тому, що висота iframeніколи насправді не змінюється.

Це означає, що ви не зможете централізувати елементи всередині iframeJavascript 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правильно призначити висоту . Це також дозволяє розташувати елементи будь-яким бажаним способом.

Тут ви можете побачити швидку та брудну демонстрацію.


1
Це єдине рішення, яке працювало на мене. Звичайно, його можна використовувати лише в тому випадку, якщо ви контролюєте вміст iframe, але в моєму випадку я це роблю. Ура!
Вінс

Хм. Схоже, ваш приклад не реагує на iOS?
BrandonReid

Це було 2 роки тому, коли я це писав. Чи можете ви подати проблему в репо?
Пірс

витративши години та години на цю проблему з Ionic / Cordova на iOS, це єдине, що спрацювало. Дякую!
Андрій

1
Це дивовижно, єдине, що спрацювало, я витратив 1 день на пошук такого рішення, як це @Pier 100pts для вас
Carlos E

5

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

Я переглянув усі рішення, наведені вище, більшість - дуже хакі.

Якщо вам не потрібна підтримка старих браузерів, просто встановіть ширину рамки на 100 Вт;

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


1
Chrome для iOS - лише Safari під ним. Він використовує WKWebView. Жоден інший механізм веб-рендерингу в iOS заборонений.
Пристань

3

Я працюю з 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 tag-

<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%;
}

Тут власне місце відіграє важливу роль у моєму випадку.
положення: відносне;

Можливо, вам теж допоможе !!!


0

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


Можливо, я неправильно реалізую ваше рішення, але коли я спробував це в своєму ізольованому тестовому випадку, тоді воно не вийшло, взагалі в iOS Safari 7.1 iPhone 4. Чи можете ви детальніше розповісти, як це має працювати?
Ідра

Гаразд, це здається, що ви неправильно зрозуміли проблему, перевірте це посилання, це ваш новий демонстраційний вміст iframe інтегрований без будь-якого додаткового CSS, застосованого до iframe. І якщо ви подивитесь на це в iOS Safari, то він все ще реагує, це тому, що на цій сторінці немає горизонтальної прокрутки, яка б змусила ширину рамки бути ширшою, ніж вікно перегляду. Як описано в запитанні, на такому веб-сайті вам не потрібно нічого робити, щоб iframe відповідав.
Ідра

так що саме ви хочете, щоб воно поводилося, наведіть приклад для даного посилання?
4dgaurav

0

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

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

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

0

насправді для мене якраз працював у ios, відключаючи прокрутку

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

та обробляти ОС за допомогою скрипту.


0

Для мене рішення CSS не спрацювали. Але програмне встановлення ширини виконує цю роботу. Для завантаження iframe програмно встановити ширину:

 $('iframe').width('100%');
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.