使用 jQuery 知道 @font-face 字体何时加载?

发布于 2024-10-06 17:01:37 字数 237 浏览 1 评论 0 原文

我正在使用 @font-face,但我讨厌 Firefox 显示默认字体,等待加载 @font-face 字体,然后替换它。所以整个页面都会闪烁新字体。

Webkit 浏览器在加载字体之前不会显示文本,而且它的外观更加清晰。

所以,我想知道 jQuery 是否可以帮助我知道页面上的所有数据(包括 @font-face 文件)何时加载,以便我可以显示我的文本?有没有一个 jQuery 方法可以告诉我什么时候所有内容都已加载?

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.

Webkit browsers just don't display the text until the font is loaded and it is a much cleaner look.

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

南汐寒笙箫 2024-10-13 17:01:37

我使用这个函数 - 在 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]);
    }
};

使用它如下:

waitForWebfonts(['MyFont1', 'MyFont2'], function() {
    // Will be called as soon as ALL specified fonts are available
});

I use this function - tested in 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
});
握住你手 2024-10-13 17:01:37

好吧,这很容易。基本上我只是将文本设置为:

a.main {visibility: hidden;}

然后添加:

$(window).bind("load", function() {
       $('#nav a.main').addClass('shown');
});

然后确保以下内容也在我的 css 文件中:

a.main.shown {visibility: visible;}

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:

a.main.shown {visibility: visible;}
夜夜流光相皎洁 2024-10-13 17:01:37

您不应该使用 $(window).bind('load') - 这将等待整个页面加载(这可能是您想要的),而不仅仅是字体。如果你想控制 @font-faces 的加载过程,请使用由 Google 和 Typekit 开发的 WebFont Loader。

您可以将它与 Google Font API、typekit 和您自己的网络字体提供商(您自己)一起使用(尽管我自己从未尝试过,因为我是 Typekit 用户。

请在此处阅读相关内容:http://code.google.com/apis/webfonts/docs/webfont_loader.html 和此处:http://blog.typekit.com/2010/05/19/typekit-and-google/

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.

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.

Read about it here: http://code.google.com/apis/webfonts/docs/webfont_loader.html and here: http://blog.typekit.com/2010/05/19/typekit-and-google/

碍人泪离人颜 2024-10-13 17:01:37

我使用 google web 字体(Crete Round Regular 和 Open Sans Regular with Bold)

您可以使用 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'); });

或 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);
})();

请注意,在第一个选项中我使用了 jQuery Deferred Object。

I use google web fonts (Crete Round Regular and 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.

小草泠泠 2024-10-13 17:01:37

也许..

创建一个 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 );

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:

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 );
国产ˉ祖宗 2024-10-13 17:01:37

我遇到了同样的问题。不知何故,我无法让 Google webfont 加载器使用 ttf 字体(尤其是中文字体)或在加载字体时发送 jquery 响应。

所以我想出了一个更基本的解决方案,在页面加载后动态更改字体时很有用。它显示字体何时正确加载。

首先,我创建一个虚拟 div,然后用“abcd”填充它,然后给它一个字体大小 40,记录 div 的宽度。当通过按钮或任何东西调用“更改字体”事件时,它应该跟踪虚拟 div 宽度的变化。宽度变化就代表字体发生了变化。

HTML 代码

<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!
    }
}

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.

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.

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!
    }
}
明月夜 2024-10-13 17:01:37

我遇到了同样的问题,我正在尝试使用readyfunction()、bind()函数和我发现的其他一些函数,但它们都不起作用。最后我找到了一种解决方案,只需在加载动画之前应用一个延迟...就像这样:

$(document).ready(function() {

setTimeout(function (){
   // The animation
},150);

}); // end ready

我知道这不是最好的解决方案,所以有人可以告诉我一个更好的解决方案吗?

谢谢!

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:

$(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!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文