Javascript 使用 jQuery 知道何时加载 @font-face 字体?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4383226/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using jQuery to know when @font-face fonts are loaded?
提问by Nic Hubbard
I am using @font-face and I hate that Firefox shows the default font, waits to load the @font-face font, then replaces it. So the whole page flashes with the new font.
我正在使用 @font-face 并且我讨厌 Firefox 显示默认字体,等待加载 @font-face 字体,然后替换它。所以整个页面都用新字体闪烁。
Webkit browsers just don't display the text until the font is loaded and it is a much cleaner look.
Webkit 浏览器在字体加载之前不会显示文本,而且看起来更干净。
So, I am wondering if jQuery could help me to know when all data on the page is loaded, including the @font-face file, so that I can then show my text? Is there a jQuery method that tells me when everything is loaded?
所以,我想知道 jQuery 是否可以帮助我知道页面上的所有数据何时加载,包括 @font-face 文件,以便我可以显示我的文本?是否有一个 jQuery 方法可以告诉我何时加载所有内容?
采纳答案by Nic Hubbard
Ok, it was pretty easy. Basically I just set my text to:
好吧,这很容易。基本上我只是将我的文本设置为:
a.main {visibility: hidden;}
and then add:
然后添加:
$(window).bind("load", function() {
$('#nav a.main').addClass('shown');
});
Then make sure that the following is also in my css file:
然后确保以下内容也在我的 css 文件中:
a.main.shown {visibility: visible;}
回答by Thomas Bachem
I use this function - tested in Safari, Chrome, Firefox, Opera, IE7, IE8, IE9:
我使用这个功能 - 在 Safari、Chrome、Firefox、Opera、IE7、IE8、IE9 中测试:
function waitForWebfonts(fonts, callback) {
var loadedFonts = 0;
for(var i = 0, l = fonts.length; i < l; ++i) {
(function(font) {
var node = document.createElement('span');
// Characters that vary significantly among different fonts
node.innerHTML = 'giItT1WQy@!-/#';
// Visible - so we can measure it - but not on the screen
node.style.position = 'absolute';
node.style.left = '-10000px';
node.style.top = '-10000px';
// Large font size makes even subtle changes obvious
node.style.fontSize = '300px';
// Reset any font properties
node.style.fontFamily = 'sans-serif';
node.style.fontVariant = 'normal';
node.style.fontStyle = 'normal';
node.style.fontWeight = 'normal';
node.style.letterSpacing = '0';
document.body.appendChild(node);
// Remember width with no applied web font
var width = node.offsetWidth;
node.style.fontFamily = font + ', sans-serif';
var interval;
function checkFont() {
// Compare current width with original width
if(node && node.offsetWidth != width) {
++loadedFonts;
node.parentNode.removeChild(node);
node = null;
}
// If all fonts have been loaded
if(loadedFonts >= fonts.length) {
if(interval) {
clearInterval(interval);
}
if(loadedFonts == fonts.length) {
callback();
return true;
}
}
};
if(!checkFont()) {
interval = setInterval(checkFont, 50);
}
})(fonts[i]);
}
};
Use it like:
像这样使用它:
waitForWebfonts(['MyFont1', 'MyFont2'], function() {
// Will be called as soon as ALL specified fonts are available
});
回答by jgradim
You should't use $(window).bind('load')
- that will wait for the whole page to load (which maybe is what you want), and not just the font. If you want to control the loading process of @font-faces use WebFont Loader, developed by Google and Typekit.
您不应该使用$(window).bind('load')
- 这将等待整个页面加载(这可能是您想要的),而不仅仅是字体。如果您想控制@font-faces 的加载过程,请使用由 Google 和 Typekit 开发的 WebFont Loader。
You can use it with Google Font API, typekit and your own webfont provider - you (although I never tried it myself as I'm a Typekit User.
您可以将它与 Google Font API、typekit 和您自己的 webfont 提供商一起使用 - 您(尽管我自己从未尝试过,因为我是 Typekit 用户。
Read about it here: http://code.google.com/apis/webfonts/docs/webfont_loader.htmland here: http://blog.typekit.com/2010/05/19/typekit-and-google/
在这里阅读:http: //code.google.com/apis/webfonts/docs/webfont_loader.html和这里:http: //blog.typekit.com/2010/05/19/typekit-and-google/
回答by uma karimov
I use google web fonts (Crete Round Regular and Open Sans Regular with Bold)
我使用谷歌网络字体(Crete Round Regular 和 Open Sans Regular with Bold)
You can use either this :
您可以使用以下任一方法:
var fonts = $.Deferred();
WebFontConfig = { google: { families: [ 'Crete+Round::latin', 'Open+Sans:400,700:latin' ] } , active : function() { fonts.resolve(); } };
(function() {
var wf = document.createElement('script');
wf.src = ('https:' == document.location.protocol ? 'https' : 'http') + '://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
wf.type = 'text/javascript';
wf.async = 'true';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(wf, s);
})();
fonts.done(function(){ alert('fonts'); });
or this :
或这个 :
WebFontConfig = { google: { families: [ 'Crete+Round::latin', 'Open+Sans:400,700:latin' ] } , active : function() { alert('fonts'); } };
(function() {
var wf = document.createElement('script');
wf.src = ('https:' == document.location.protocol ? 'https' : 'http') + '://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
wf.type = 'text/javascript';
wf.async = 'true';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(wf, s);
})();
Note that in the first option i used jQuery Deferred Object.
请注意,在第一个选项中,我使用了 jQuery Deferred Object。
回答by Sven Spruijt
Perhaps..
也许..
Create a z-index: -10 div and fill it with a lot of text (with a 'normal' font). At document.ready() or another event:
创建一个 z-index: -10 div 并用大量文本填充它(使用“普通”字体)。在 document.ready() 或其他事件中:
var originalnumber = $( div ).width() + $( div ).height() + $( div ).offset().top + $( div ).offset().left;
$( div ).css( 'font-family', 'MyPrettyWebfont' );
var interval = setInterval( function() {
var number = $( div ).width() + $( div ).height() + $( div ).offset().top + $( div ).offset().left;
if ( number !== originalnumber ) {
// webfont is loaded and applied!
clearInterval( interval );
}
}, 10 );
回答by Tien Lu
I got the same problem. And somehow i can't get Google webfont loader to work with ttf font (especially chinese fonts) or send a jquery response when font is loaded.
我遇到了同样的问题。不知何故,我无法让 Google webfont 加载器使用 ttf 字体(尤其是中文字体)或在加载字体时发送 jquery 响应。
So I came up with this a more basic solution, useful when changing font dynamically after page is loaded. it shows when the font face is properly loaded.
所以我想出了一个更基本的解决方案,在页面加载后动态更改字体时很有用。它显示字体何时正确加载。
First i create a dummy div and then fill it with 'abcd' and then give it a font size 40, record the width of the div. When the 'change font' event is invoked via a button or anything, it should track the dummy div width changes. Width changes would represent that the font has change.
首先我创建一个虚拟 div,然后用“abcd”填充它,然后给它一个字体大小 40,记录 div 的宽度。当通过按钮或任何东西调用“更改字体”事件时,它应该跟踪虚拟 div 宽度的变化。宽度变化将代表字体发生变化。
HTML CODE
代码
<style>
@font-face {
font-family: 'font1';
src:url('somefont.ttf') format('truetype');
}
</style>
<div id="dummy" style="border:1px solid #000; display:inline-block">abdc</div>
<!--simple button to invoke the fontchange-->
<input type="button" onclick="javascript:changefont('font1')" value="change the font"/>
JQuery
查询
//create a variable to track initial width of default font
var trackwidth
//when change font is invoke
function changefont(newfont)
{
//reset dummy font style
$('#dummy').css('font-family','initial !important;');
$('#dummy').css({'font-size':'40px'});
$('#dummy').html('abcd');
//ensure that trackwidth is only recorded once of the default font
if(trackwidth==null)
{
trackwidth=( $('#dummy').width());
}
//apply new font
$('#dummy').css('font-family',newfont);
checkwidth()
}
function checkwidth()
{
//check if div width changed
if($('#dummy').width() == trackwidth)
{
//if div never change, detect again every 500 milisecs
setTimeout(checkwidth, 500);
}
else
{
//do something, font is loaded!
}
}
回答by Fernando
I've got the same problem and I'm trying with the readyfunction(), the bind() function and some others that I found, but none of them works. Finaly I found one solution, just aplying one delay before the animation is loaded... like this:
我遇到了同样的问题,我正在尝试使用 readyfunction()、bind() 函数和我发现的其他一些函数,但它们都不起作用。最后我找到了一个解决方案,只是在加载动画之前延迟一个......像这样:
$(document).ready(function() {
setTimeout(function (){
// The animation
},150);
}); // end ready
I know this is not the best solution, so can someone tell me one better??
我知道这不是最好的解决方案,所以有人可以告诉我更好的解决方案吗?
Thanks!
谢谢!