Подтвердить что ты не робот

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, добавьте ответ, в котором суммируется то, что вы пробовали, и я буду перенаправлять вас: -)

4b9b3361

Ответ 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>