Using jQuery to know when @font-face fonts are loaded?

前端 未结 7 2060
日久生厌
日久生厌 2020-11-28 08:35

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.

相关标签:
7条回答
  • 2020-11-28 08:55

    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.

    0 讨论(0)
  • 2020-11-28 08:56

    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!

    0 讨论(0)
  • 2020-11-28 09:04

    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;}
    
    0 讨论(0)
  • 2020-11-28 09:04

    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 );
    
    0 讨论(0)
  • 2020-11-28 09:07

    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
    });
    
    0 讨论(0)
  • 2020-11-28 09:16

    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!
        }
    }
    
    0 讨论(0)
提交回复
热议问题