web-dev-qa-db-ja.com

フォント(@ font-face)が既にロードされているかどうかを知る方法は?

Font-Awesomeを使用していますが、フォントファイルが読み込まれていない間、アイコンはwithで表示されます。

そのため、これらのアイコンにdisplay:noneファイルがロードされていない間。

@font-face {
  font-family: "FontAwesome";
  src: url('../font/fontawesome-webfont.eot');
  src: url('../font/fontawesome-webfont.eot?#iefix') format('eot'), url('../font/fontawesome-webfont.woff') format('woff'), url('../font/fontawesome-webfont.ttf') format('truetype'), url('../font/fontawesome-webfont.svg#FontAwesome') format('svg');
  font-weight: normal;
  font-style: normal;
}

これらのファイルが読み込まれ、アイコンを表示できるようになったことを確認するにはどうすればよいですか?

編集:フォントがページ全体の前にロードされる可能性があるため、ページがロードされた(オンロード)ときは話していません。

75
Shankar Cabus

GitHubで: https://github.com/patrickmarabeas/jQuery-FontSpy.js

基本的に、この方法は2つの異なるフォントで文字列の幅を比較することで機能します。テスト対象のフォントとしてComic Sansを使用しています。これは、Webセーフフォントの中で最も異なっており、使用するカスタムフォントとは十分に異なるためです。さらに、非常に大きなフォントサイズを使用しているため、わずかな違いでも明らかです。 Comic Sans文字列の幅が計算されると、フォントファミリがカスタムフォントに変更され、Comic Sansにフォールバックされます。オンにすると、文字列要素の幅が同じ場合、Comic Sansの代替フォントが引き続き使用されます。そうでない場合は、フォントが機能しているはずです。

フォントのロード検出のメソッドを、開発者がフォントがロードされているかどうかに基づいて要素をスタイルできるように設計されたjQueryプラグインに書き直しました。フェイルセーフタイマーが追加されたため、カスタムフォントの読み込みに失敗した場合でもユーザーはコンテンツを残しません。使い勝手が悪いだけです。

また、フォントの読み込み中および失敗時にクラスの追加と削除を含めることで何が起こるかをより細かく制御できるようにしました。これで、フォントに対して何でもできます。フォントサイズ、行間隔などを変更して、フォールバックフォントをできる限りカスタムに近づけて、レイアウトが損なわれないようにし、ユーザーが期待するエクスペリエンスを得るようにすることをお勧めします。

以下にデモを示します。 http://patrickmarabeas.github.io/jQuery-FontSpy.js

以下を.jsファイルにスローして参照します。

(function($) {

    $.fontSpy = function( element, conf ) {
        var $element = $(element);
        var defaults = {
            font: $element.css("font-family"),
            onLoad: '',
            onFail: '',
            testFont: 'Comic Sans MS',
            testString: 'QW@HhsXJ',
            delay: 50,
            timeOut: 2500
        };
        var config = $.extend( defaults, conf );
        var tester = document.createElement('span');
            tester.style.position = 'absolute';
            tester.style.top = '-9999px';
            tester.style.left = '-9999px';
            tester.style.visibility = 'hidden';
            tester.style.fontFamily = config.testFont;
            tester.style.fontSize = '250px';
            tester.innerHTML = config.testString;
        document.body.appendChild(tester);
        var fallbackFontWidth = tester.offsetWidth;
        tester.style.fontFamily = config.font + ',' + config.testFont;
        function checkFont() {
            var loadedFontWidth = tester.offsetWidth;
            if (fallbackFontWidth === loadedFontWidth){
                if(config.timeOut < 0) {
                    $element.removeClass(config.onLoad);
                    $element.addClass(config.onFail);
                    console.log('failure');
                }
                else {
                    $element.addClass(config.onLoad);
                    setTimeout(checkFont, config.delay);
                    config.timeOut = config.timeOut - config.delay;
                }
            }
            else {
                $element.removeClass(config.onLoad);
            }
        }
        checkFont();
    };

    $.fn.fontSpy = function(config) {
        return this.each(function() {
            if (undefined == $(this).data('fontSpy')) {
                var plugin = new $.fontSpy(this, config);
                $(this).data('fontSpy', plugin);
            }
        });
    };

})(jQuery);

プロジェクトに適用する

.bannerTextChecked {
        font-family: "Lobster";
        /* don't specify fallback font here, do this in onFail class */
}

$(document).ready(function() {

    $('.bannerTextChecked').fontSpy({
        onLoad: 'hideMe',
        onFail: 'fontFail anotherClass'
    });

});

そのFOUCを削除してください!

.hideMe {
    visibility: hidden !important;
}

.fontFail {
    visibility: visible !important;
    /* fall back font */
    /* necessary styling so fallback font doesn't break your layout */
}

編集:FontAwesomeの互換性は適切に機能せず、異なるバージョンで問題が発生したため削除されました。ハッキングの修正はここにあります: https://github.com/patrickmarabeas/jQuery-FontFaceSpy.js/issues/1

42
Patrick

WebFont Loadergithub repo )を試してください。これはGoogleとTypekitによって開発されました。

この例 最初にデフォルトのセリフフォントでテキストを表示します。フォントがロードされた後、指定されたフォントでテキストが表示されます。 (このコードは、他のすべての最新ブラウザーでFirefoxのデフォルトの動作を再現します。)

17
cassi.lup

他のソリューションとは異なるアプローチを次に示します。

FontAwesome 4.1.0を使用してWebGLテクスチャを構築しています。それは、fa-squareをレンダリングするために小さなキャンバスを使用し、そのキャンバスのピクセルをチェックして、ロードされているかどうかをテストするというアイデアを与えました:

function waitForFontAwesome( callback ) {
   var retries = 5;

   var checkReady = function() {
      var canvas, context;
      retries -= 1;
      canvas = document.createElement('canvas');
      canvas.width = 20;
      canvas.height = 20;
      context = canvas.getContext('2d');
      context.fillStyle = 'rgba(0,0,0,1.0)';
      context.fillRect( 0, 0, 20, 20 );
      context.font = '16pt FontAwesome';
      context.textAlign = 'center';
      context.fillStyle = 'rgba(255,255,255,1.0)';
      context.fillText( '\uf0c8', 10, 18 );
      var data = context.getImageData( 2, 10, 1, 1 ).data;
      if ( data[0] !== 255 && data[1] !== 255 && data[2] !== 255 ) {
         console.log( "FontAwesome is not yet available, retrying ..." );
         if ( retries > 0 ) {
            setTimeout( checkReady, 200 );
         }
      } else {
         console.log( "FontAwesome is loaded" );
         if ( typeof callback === 'function' ) {
            callback();
         }
      }
   }

   checkReady();
};

キャンバスを使用するため、かなり最新のブラウザーが必要ですが、IE8でもポリフィルで動作する可能性があります。

9
Leeft

タイマーをまったく使用せずに@ font-faceが既にロードされているかどうかを確認する別の方法は次のとおりです。慎重に作成された要素のサイズが変更されると、「スクロール」イベントを使用して瞬間的なイベントを受信します。

ブログ投稿 の書き方を書き、 Githubのライブラリ を公開しました。

3
smnh