Как сделать iframe 100% высоты в зависимости от его содержания
Я видел много людей, спрашивающих, как сделать iframe 100% высоты. Это может быть легко заархивировано с помощью некоторого CSS. Это заставит iframe отображать 100% относительно экрана устройства. Но как сделать iframe 100% высоты в соответствии с его содержанием?
Вот мой текущий код, чтобы сделать 100% iframe в соответствии с экраном устройства:
iframe {
display: block;
background: #000;
border: none;
height: 100vh;
width: 100vw;
}
<iframe src="https://...">Your Browser Does Not Support iframes!</iframe>
allowfullscreen
а также position:absolute
не помогло, кроме как разбить шаблон моего сайта. Это лучшее, что я могу сделать, не разбивая основной CSS. Пожалуйста помоги...
Изменить: содержание iframe реагирует с помощью
<meta name="viewport" content="width=device-width,initial-scale=1">
так что заданная высота с использованием javascript тоже не сработала. Возможно, есть ли способ использовать единицы измерения высоты?
em
, ex
, rem
так далее? Или сделать это определенный процент vw
?
4 ответа
Просто хотел поделиться своим решением и волнением. Мне потребовалось целых четыре дня интенсивных исследований и неудач, но я думаю, что нашел изящный способ сделать фреймы полностью адаптивными! Ура!
Я испробовал массу разных подходов... Я не хотел использовать туннель двусторонней связи, как в
postMessage
потому что это неудобно для одинакового происхождения и сложно для перекрестного происхождения (поскольку ни один администратор не хочет открывать двери и реализовывать это от вашего имени).
Я пробовал использовать MutationObservers, и мне все еще требовалось несколько слушателей событий (изменение размера, щелчок,..), чтобы гарантировать, что каждое изменение макета обрабатывается правильно. - Что, если скрипт переключает видимость элемента? Или что, если он динамически предварительно загружает больше контента по запросу? - Другая проблема заключалась в получении откуда-то точной высоты содержимого iframe. Большинство людей предлагают использовать
scrollHeight
или же
offsetHeight
, или их комбинацию с помощью
Math.max
. Проблема в том, что эти значения не обновляются до тех пор, пока элемент iframe не изменит свои размеры. Для этого вы можете просто сбросить
iframe.height = 0
прежде чем схватить
scrollHeight
, но здесь есть еще кое-что. Итак, к черту это.
Затем у меня появилась другая идея поэкспериментировать с
requestAnimationFrame
избавиться от моих событий и ада наблюдателей. Теперь я мог немедленно реагировать на каждое изменение макета, но у меня по-прежнему не было надежного источника, из которого можно было бы сделать вывод о высоте содержимого iframe. И я обнаружил
getComputedStyle
, случайно! Это было просветление! Все просто щелкнуло.
Что ж, посмотрите код, который я смог извлечь из своих бесчисленных попыток.
function fit() {
var iframes = document.querySelectorAll("iframe.gh-fit")
for(var id = 0; id < iframes.length; id++) {
var win = iframes[id].contentWindow
var doc = win.document
var html = doc.documentElement
var body = doc.body
var ifrm = iframes[id] // or win.frameElement
if(body) {
body.style.overflowX = "scroll" // scrollbar-jitter fix
body.style.overflowY = "hidden"
}
if(html) {
html.style.overflowX = "scroll" // scrollbar-jitter fix
html.style.overflowY = "hidden"
var style = win.getComputedStyle(html)
ifrm.width = parseInt(style.getPropertyValue("width")) // round value
ifrm.height = parseInt(style.getPropertyValue("height"))
}
}
requestAnimationFrame(fit)
}
addEventListener("load", requestAnimationFrame.bind(this, fit))
Вот и все, да! - В вашем HTML-коде напишите
<iframe src="page.html" class="gh-fit gh-fullwidth"></iframe>
. В
gh-fit
- это просто поддельный класс CSS, используемый для определения того, на какие элементы iframe в вашей DOM должен воздействовать скрипт. В
gh-fullwidth
это простой класс CSS с одним правилом
width: 100%;
.
Приведенный выше скрипт автоматически извлекает все фреймы из DOM, у которых есть
.gh-fit
присвоенный класс. Затем он берет и использует предварительно рассчитанные значения стиля для ширины и высоты из
document.getComputedStyle(iframe)
, которые всегда содержат идеальный размер этого элемента!!! Просто отлично!
Обратите внимание: это решение не работает с разными источниками (как и любое другое решение без стратегии двусторонней связи, такой как IFrameResizer). JS просто не может получить доступ к DOM iframe, если он вам не принадлежит.
Единственное другое решение с перекрестным происхождением, которое я могу придумать, - это использовать прокси, например https://github.com/gnuns/allorigins. Но это потребует глубокого копирования каждого запроса, который вы делаете - другими словами, вы "крадете" весь исходный код страницы (чтобы сделать его своим и позволить JS получить доступ к DOM), и вы исправляете каждую ссылку / путь в этом источнике, чтобы он также проходит через прокси. Процедура повторного связывания - сложная, но выполнимая.
Я, наверное, попробую себя решить с этой проблемой перекрестного происхождения, но это в другой день. Наслаждайтесь кодом!:)
Не существует единственного способа CSS для установки высоты iframe в соответствии с его содержимым. Вам нужно использовать JavaScript, чтобы получить высоту содержимого iframe, а затем установить высоту iframe.
Как этого добиться с помощью JavaScript ответили и хорошо объяснили в следующих вопросах:
Попробуйте установить position
в fixed
, как это:
height: 100%;
width: 100%;
position:fixed;
Или вот так:
height: 100vh;
width: 100vw;
position:fixed;
Назначьте своему iframe собственный идентификатор, и тогда вы сможете установить для него значение vw или vh.