小编典典

如何知道字体(@ font-face)是否已经加载?

javascript

我使用的是Font-Awesome,但未加载字体文件时,图标显示为。

因此,我希望这些图标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;
}

我怎么知道这些文件已经加载,我终于可以显示图标了?

编辑: 我不是在说页面何时加载(onload),因为字体可以在整个页面之前加载。


阅读 1548

收藏
2020-05-01

共1个答案

小编典典

现在在GitHub上:

本质上,该方法通过比较两种不同字体的字符串宽度来工作。我们使用Comic
Sans作为测试字体,因为它是网络安全字体中最不同的字体,希望与您将要使用的任何自定义字体都足够不同。此外,我们使用了非常大的字体,因此即使很小的差异也会很明显。计算出Comic
Sans字符串的宽度后,字体系列将更改为您的自定义字体,而回退到Comic Sans。选中该选项后,如果字符串元素的宽度相同,则仍将使用Comic
Sans的后备字体。如果没有,您的字体应该可以使用。

我将字体加载检测的方法重写为一个jQuery插件,该插件旨在使开发人员能够根据是否已加载字体来对元素进行样式设置。添加了故障安全计时器,因此,如果自定义字体无法加载,则不会为用户留下任何内容。那只是不好的可用性。

我还增加了对字体加载过程中发生的事情的控制,并通过添加和删除类来控制失败。现在,您可以对字体进行任何操作。我只建议修改字体大小,行距等,以使后备字体尽可能接近自定义字体,以使布局保持完整,并为用户带来预期的体验。

将以下内容放入.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兼容性被删除,因为它不能正常工作,并遇到了不同版本的问题。

2020-05-01