IE8 веб-шрифт iframe ошибки обходные пути
Это сообщение в блоге (немного раздражающая страница там) (и это не мой блог, кстати) описывает странную ошибку, с которой я столкнулся вчера Только Internet Explorer 8. Ошибка включает в себя веб-шрифты .EOT и элементы <iframe>
.
Я не изучил подробный триггер ошибки, но в основном это тот случай, когда страница, использующая веб-шрифт, который загружает контент в <iframe>
, так что кадр также использует веб-шрифт, становится "испорченным" браузера. Ранее текст ОК, отображаемый с помощью веб-шрифта, внезапно переключается на ужасный Arial или что-то еще, своеобразное. Иногда он откидывается назад, только для того, чтобы снова ухудшаться при случайных пользовательских взаимодействиях, таких как мыши.
В этом блоге есть пример. Чтобы уточнить, это страница, которая запуталась, а не страница в <iframe>
(по крайней мере, это случай, который до сих пор был в моем опыте).
Кто-нибудь нашел лучшее обходное решение, чем то, что было предложено в этом блоге, чтобы заставить "перезагрузить" элемент CSS <link>
, откуда появились объявления @font-face
? (Я мог бы это сделать, но это было бы незначительной болью, плюс это заставило бы меня перенести мою настройку шрифта из моего документа <head>
, который, если я помню, является проблемой производительности, мне придется всматриваться и обнаруживать, что лакомый кусочек снова.)
edit — Обновление
OK здесь тестовая страница. Здесь главная (контейнерная) страница:
<!DOCTYPE html>
<html>
<head>
<style id='font_style'>
@font-face {
font-family: 'bold-display';
src: url('DejaVuSans-Bold.eot');
}
</style>
<style>
.fancy { font-family: bold-display, "franklin gothic medium", "verdana", sans-serif; font-size: 32px; }
iframe { width: 500px; height: 200px; }
#floater {
position: absolute;
top: 100px; left: 100px;
display: none;
}
#floater.showing {
display: block;
}
</style>
<script>
function load() {
var frame = document.createElement('iframe'),
floater = document.getElementById('floater'),
target = document.getElementById('target');
frame.src = 'frame.html';
target.appendChild(frame);
floater.className += 'showing';
}
function unload() {
var floater = document.getElementById('floater'),
target = document.getElementById('target');
target.innerHTML = '';
floater.className = floater.className.replace(/\bshowing\b/g, '');
}
</script>
</head>
<body>
<div class='fancy'>Hello World</div>
<button type='button' onclick='load()'>Click Me</button>
<div id='floater'>
<div id='target'></div>
<button type='button' onclick='unload()'>Close</button>
</body>
</html>
Страница фрейма имеет те же @font-face
и фиктивные сообщения.
Проблема, похоже, связана с использованием загруженных шрифтов со списком более чем одного альтернативного шрифта. Я (без уважительной причины) бросил в пару подобных более распространенных шрифтов в своих значениях "font-family". Когда я отбросил их обратно:
.title { font-family: bold-display, sans-serif; }
тогда проблема исчезла (или, по крайней мере, она до сих пор ушла).
Спасибо тем, кто помог. Чтобы @albert, добавьте ответ, в котором суммируется то, что вы пробовали, и я буду перенаправлять вас: -)
Ответы
Ответ 1
Итак, нет производительности с последующим (пока ваш CSS достаточно размер), вы можете оставить тег <link>
в <head>
, и он работает без проблем, но вы по-прежнему в основном " перезагружая 'ваши элементы <link>
(хотя вы не делаете этого, сбросив их URL-адрес).
При удалении элемента <iframe>
просто выполните следующее:
var sheets = document.styleSheets;
for(var s = 0, slen = sheets.length; s < slen; s++) {
sheets[s].disabled = true;
sheets[s].disabled = false;
}
Перезагрузка - это все, о чем я действительно могу думать, поскольку работаю, поскольку она, кажется, удаляет ее в сборке мусора из <iframe>
. Настройте тестовую страницу, которая, очевидно, работает только для IE 8.
Примечание. Я изначально не смог повторно воспроизвести эту проблему с помощью веб-шрифтов Google и должен был специально загрузить шрифт .eot
для использования для этого. Таким образом, ваша работа, возможно, сначала использует шрифты WOFF, и при необходимости загружать EOT.
Не совсем уверен, что это то, что вы искали, но если это не так, уточните, и я отредактирую по мере необходимости.
Обновление 1: причина
Итак, я сузил причину проблемы. Я могу только воспроизвести, если произойдет следующее (и это неприятный человек).
- И
<iframe>
содержится в родительском элементе
- Изменен класс родительского элемента
- Класс не меняет
display
элемента, к которому он применяется (или действительно, если он не меняет общий дисплей в элементе <iframe>
)
И, из того, что я могу сказать, да, это должно быть имя класса. Я не смог воспроизвести, учитывая те же шаги в id
элемента. Шутки в сторону. Это неприятно. Я продолжу копать немного.
Обновление 2: Вторичная причина
Если <iframe>
не полностью находится в окне браузера при рисовании, он не загрузит шрифт в окне <iframe>
и выгрузит шрифт для главного окна всякий раз, когда ему нужно перерисовать страницу (в первую очередь когда он изменяется). Это грубая ошибка.
Обновление 3: Что должно быть решением
Вместо использования display: none;
установите высоту и ширину элемента как 0px
и overflow: hidden;
, и вы получите тот же эффект, что и отображение none, но оно не удалит его из DOM, тем самым не перерисовывая страницу и не используя шрифт. Моя тестовая страница от ранее была обновлена, поэтому вы можете увидеть влияние на то, что раньше было ошибкой.
Ответ 2
Если вы только что создали синтаксис кросс-браузера @font-face
через fontsquirrel.com, я не думаю, что у вас даже была проблема. вы хотите внедрить:
@font-face{
font-family: 'DejaVuSansBook';
src: url('DejaVuSans-webfont.eot'); /* ie9 compat mode */
src: url('DejaVuSans-webfont.eot?#iefix') format('eot'), /* ie 6-7-8 */
url('DejaVuSans-webfont.woff') format('woff'), /* modern browsers */
url('DejaVuSans-webfont.ttf') format('truetype'), /* Safari, Android, iOS */
url('DejaVuSans-webfont.svg#webfontLXhJZR1n') format('svg'); /* Legacy iOS */
}
вы также можете использовать загрузчик webfont script, если вы обнаружите, что синтаксис не работает. Я не сравнивал функциональность с приведенным выше кодом (я уверен, что он работает), это тип js и googlefonts, чтобы загрузить их шрифты.
Ответ 3
Я столкнулся с этим q & while, исследуя очень похожую ситуацию, за исключением того, что iframe не участвует. Все, что нужно, это использовать веб-шрифт google и множество плавающих div, чтобы заставить IE8 отображать текст по-разному после перезагрузки. Прочитав это
Проблема, похоже, связана с использованием загруженных шрифтов со списком более чем одного альтернативного шрифта.
Я изменил стек шрифтов в моем css только на одну альтернативу, и ошибка исчезла.
Спасибо, что указал мне в правильном направлении!
Ответ 4
Решение, которое я закончил, было
@font-face {
font-family: 'NewsGothicFSMedium';
src: url('NewsGothic-Medium-webfont.eot');
src: url('NewsGothic-Medium-webfont.eot?#iefix') format('embedded-opentype'),
url('NewsGothic-Medium-webfont.woff') format('woff'),
url('NewsGothic-Medium-webfont.ttf') format('truetype'),
url('NewsGothic-Medium-webfont.svg#webfont') format('svg');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'NewsGothicFSMediumIframe';
src: url('NewsGothic-Medium-webfont.eot');
src: url('NewsGothic-Medium-webfont.eot?#iefix') format('embedded-opentype'),
url('NewsGothic-Medium-webfont.woff') format('woff'),
url('NewsGothic-Medium-webfont.ttf') format('truetype'),
url('NewsGothic-Medium-webfont.svg#webfont') format('svg');
font-weight: normal;
font-style: normal;
}
Затем просто укажите семейство шрифтов Iframe в iframe css. Его немного больше css, но я думаю, что лучше, чем перезагрузить css, если вы используете только несколько шрифтов.
Ответ 5
Ни одно из предлагаемых нами решений не помогло нам, поэтому нам пришлось просто сохранить всю страницу скрытой, пока страница не была загружена. Мы сделали это со следующим фрагментом кода:
<!--[if lte IE 8]>
<style type="text/css">
html {
visibility: hidden;
}
</style>
<script type="text/javascript">
$(window).load(function() {
$('html').css('visibility', 'visible');
});
</script>
<![endif]-->
Ответ 6
IE < 9 имеет ошибку в способе обработки атрибута src шрифта.
Согласно https://github.com/stubbornella/csslint/wiki/Bulletproof-font-face, вы можете избежать этого, просто добавив вопросительный знак после первого URL-адреса шрифта и обманом, как браузер интерпретирует URL-адрес. Работала для меня как шарм.
Ответ 7
Проблема, с которой мы столкнулись, по-видимому, заключалась в том, что при невозможности загрузки iframe с тем же именем (404 в нашем случае) IE (иногда) выгружает шрифт на главной странице. Наше решение состояло в том, чтобы переименовать шрифт на iframed-странице (в случае, если шрифт не может быть загружен по какой-то причине вне нашего контроля) и убедитесь, что он правильно загружен нормально.
Ответ 8
Моим решением было установить только одну возможность типографики для IE8. Пример:
general.css
@font-face {
font-family: 'patua-one'; /PatuaOneRegular';/
src: url('../fonts/PatuaOne-Regular-webfont.eot');
src: url('../fonts/PatuaOne-Regular-webfont.eot?#iefix') format('embedded-opentype'),
url('../fonts/PatuaOne-Regular-webfont.woff') format('woff'),
url('../fonts/PatuaOne-Regular-webfont.ttf') format('truetype'),
url('../fonts/PatuaOne-Regular-webfont.svg#PatuaOneRegular') format('svg');
font-weight: normal;
font-style: normal;
}
body {
font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
}
h1,h2,h3,h4,h5,h6 {
font-family: patua-one,Arial,Helvetica Neue,Helvetica,sans-serif;
}
<!--[if IE 8]>
<link rel="stylesheet" type="text/css" href="ie8.css">
<![endif]-->
ie8.css
body {
font-family: Arial;
}
h1,h2,h3,h4,h5,h6 {
font-family: patua-one;
}
Ответ 9
У меня была аналогичная проблема, но она была с простым набором фреймов, а не с динамическими iframe. Riffing по ответе от ktash, это централизует взлом в кадре верхнего уровня, не затрагивая все страницы, которые могут загружаться вокруг набора фреймов.
Условный блок переопределит обработчик onload только для IE8.
По-прежнему существует FOUC, но по крайней мере ситуация исправляет себя, а не требует, чтобы пользователь перемещался.
<html>
<head>
<script>
function markFrameLoaded() {
// noop for the well behaved browsers of the world
}
</script>
<!--[if IE 8]>
<script>
function markFrameLoaded() {
var frameCount = window.frames.length;
for ( var f = 0 ; f < frameCount ; f++ ) {
var styleCount = window.frames[f].document.styleSheets.length;
for ( var s = 0 ; s < styleCount ; s++ ) {
var sheet = window.frames[f].document.styleSheets[s];
sheet.disabled = true;
sheet.disabled = false;
}
}
}
</script>
<![endif]-->
</head>
<frameset rows="*,*">
<frame src="top.html" onload="markFrameLoaded()">
<frame src="bottom.html" onload="markFrameLoaded()">
</frameset>
</html>