web-dev-qa-db-fra.com

Vous utilisez jQuery pour savoir quand les polices @ font-face sont chargées?

J'utilise @ font-face et je déteste que Firefox affiche la police par défaut, attend de charger la police @ font-face, puis la remplace. La page entière clignote donc avec la nouvelle police.

Les navigateurs Webkit n’affiche pas le texte tant que la police n’a pas été chargée et son aspect est beaucoup plus net.

Donc, je me demande si jQuery pourrait m'aider à savoir quand toutes les données de la page sont chargées, y compris le fichier @ font-face, afin que je puisse ensuite afficher mon texte? Existe-t-il une méthode jQuery qui me dit quand tout est chargé?

40
Nic Hubbard

Ok, c'était plutôt facile. Fondamentalement, je viens de définir mon texte à:

a.main {visibility: hidden;}

puis ajoutez:

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

Ensuite, assurez-vous que ce qui suit est également dans mon fichier css:

a.main.shown {visibility: visible;}
25
Nic Hubbard

J'utilise cette fonction - testée dans 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]);
    }
};

Utilisez-le comme:

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

Vous ne devriez pas utiliser $(window).bind('load') - cela va attendre le chargement de la page entière (ce qui est peut-être ce que vous voulez), et pas seulement la police. Si vous souhaitez contrôler le processus de chargement de @ font-faces, utilisez WebFont Loader, développé par Google et Typekit.

Vous pouvez l'utiliser avec l'API Google Font, Typkit et votre propre fournisseur de police Web - vous (même si je ne l'ai jamais essayé moi-même, car je suis un utilisateur Typekit.

Lisez à ce sujet ici: http://code.google.com/apis/webfonts/docs/webfont_loader.html et ici: http://blog.typekit.com/2010/05/19/typekit -et-google/

17
jgradim

J'utilise des polices Web Google (Crete Round Regular et Open Sans Regular avec Gras)

Vous pouvez utiliser soit ceci:

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'); });

ou ca :

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

Notez que dans la première option j’utilisais jQuery Deferred Object.

4
uma karimov

Peut-être ..

Créez un index z: -10 div et remplissez-le avec beaucoup de texte (avec une police 'normale') Sur document.ready () ou un autre événement:

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 );
1
Sven Spruijt

J'ai le même problème. Et d’une manière ou d’une autre, je ne parviens pas à faire fonctionner Google webfont loader avec la police ttf (notamment les polices chinoises) ni à envoyer une réponse jQuery lorsque la police est chargée. 

J'ai donc proposé cette solution plus basique, utile lors du changement de police dynamique après le chargement de la page. il montre quand la police est correctement chargée.

Tout d’abord, je crée un div factice, puis je le remplis par 'abcd', puis lui donne une taille de police de 40, et enregistre la largeur de la div. Lorsque l'événement 'changer de police' est appelé via un bouton ou autre, il doit suivre les modifications de la largeur de la division factice. Les changements de largeur signifieraient que la police a changé.

CODE 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!
    }
}
0
Tien Lu