【发布时间】:2021-11-18 15:16:41
【问题描述】:
当我通过用户 UI 加载不同的 Google 字体时,我尝试了不同的方法来避免 FOUT(无样式文本闪烁)。
最初,我认为我可以在链接元素上侦听加载事件,用于从 Google API 请求字体。然而,这个链接并不下载字体本身——它只是下载链接到实际字体文件的@font-face。
此外,当您的浏览器下载了@font-face 时,它显然不会下载它链接到的实际字体,直到该字体被页面上的可见文本元素实际使用。 “可见”表示该元素不能通过 display: none 隐藏。
因此,经过进一步挖掘,我决定使用CSS Font Loading API,因为它的设计正是为了处理这些事情。然而,令我失望的是,我仍然得到一个短的 FOUT。我加载谷歌字体的代码:
function requestGoogleFont(fontFamily, fontWeight, fontStyle, doOnLoad) {
let font = [fontStyle, fontWeight, '14px', fontFamily + ', ', 'sans-serif'].join(' '),
headElement = pageFrameContents.head,
fontVariant = fontStyle === 'italic' ? fontWeight + 'italic': fontWeight,
url = 'https://fonts.googleapis.com/css?family=' + fontFamily.split(' ').join('+') + ':' + fontVariant,
link = html.createAndAppend(headElement, '<link rel="stylesheet">'); // Adds a link element to the head element
fontLoadInitiator.style.font = font;
pageFrame.contentWindow.document.fonts.load(font)
.then(function(returned) {
doOnLoad();
});
link.setAttribute("href", url);
}
您可能已经从代码中猜到了,字体被添加到 iframe 中的文档中。回调 doOnLoad 只是调整 CSS 以应用所选字体。 fontLoadInitiator 指的是页面上的段落元素,其样式为不可见,透明度为:0。它包含一些文本,其作用是让浏览器在下载@font-face 后立即下载字体。
我很失望,即使在使用 CSS 字体加载 API 之后我仍然得到一个短的 FOUT。我可以通过使用一个小的超时来隐藏闪光灯,但实际上我不应该这样做,因为回调应该只在字体完全下载后运行。我没主意了。我希望你们中的一些人过去曾与这只野兽战斗过,并有一些有用的经验可以分享。否则,我唯一的选择是超时(颤抖!)。顺便说一句,我使用的是 Google Chrome 版本 93。
【问题讨论】:
-
更快的无样式文本> 更慢的样式文本,不要与野兽搏斗,让文本尽快展现并拥抱FOUT
-
@Kareem,谢谢。但这并不是真正的页面加载问题,而是 UI 问题。文本已经可见并且可以通过 UI 进行操作。这很奇怪,因为当一个元素的字体发生变化时,它会在应用新字体之前瞬间变为无样式。
标签: javascript css google-webfonts