programing

글꼴(@font-face)이 이미 로드되었는지 어떻게 알 수 있습니까?

mailnote 2023. 10. 28. 08:06
반응형

글꼴(@font-face)이 이미 로드되었는지 어떻게 알 수 있습니까?

폰트 대박을 사용하고 있는데 폰트 파일이 로드되지 않는 동안에는 아이콘이 와 함께 나타납니다.

그래서 이 아이콘들이.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;
}

파일이 로드되고 아이콘이 표시되는지 어떻게 알 수 있습니까?

편집: 페이지가 로드될 때(로드될 때), 폰트가 전체 페이지보다 먼저 로드될 수 있기 때문에 말하는 것이 아닙니다.

이제 GitHub에서: https://github.com/patrickmarabeas/jQuery-FontSpy.js

기본적으로 이 방법은 서로 다른 두 글꼴에서 문자열의 너비를 비교하여 작동합니다.코믹 산스는 웹 안전 글꼴 중 가장 다르며 사용할 맞춤 글꼴과 충분히 다르길 바라기 때문에 테스트할 글꼴로 사용하고 있습니다.또한 우리는 매우 큰 글자 크기를 사용하고 있기 때문에 작은 차이도 분명히 드러날 것입니다.코믹 산스 문자열의 너비가 계산되면 글꼴 패밀리가 사용자 정의 글꼴로 변경되고 코믹 산스로 폴백됩니다.이 옵션을 선택하면 문자열 요소의 너비가 동일한 경우 코믹 산스의 폴백 글꼴이 계속 사용 중입니다.그렇지 않은 경우 글꼴을 사용할 수 있어야 합니다.

글꼴 로드 감지 방법을 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 */
}

편집: 글꼴이 제대로 작동하지 않아 다른 버전에서 문제가 발생하여 일부 호환성이 제거되었습니다.해킹에 대한 해결책은 여기 https://github.com/patrickmarabeas/jQuery-FontFaceSpy.js/issues/1 에서 찾을 수 있습니다.

Google과 Typekit이 개발한 WebFont Loader (gitub repo)를 사용해 보십시오.

이 예제는 먼저 기본 serif 글꼴로 텍스트를 표시한 다음 글꼴을 로드한 후 지정된 글꼴로 텍스트를 표시합니다. (이 코드는 다른 모든 최신 브라우저에서 Firefox의 기본 동작을 재현합니다.)

사실, 모든 글꼴이 다운로드 또는 로드되기 시작하거나 완전히 다운로드되지 않거나 일부 오류가 발생하는 것을 이해하는 좋은 방법이 있지만 특정 글꼴만을 위한 것은 아닙니다. 다음 코드에 주의하십시오.

document.fonts.onloading = () => {
  // do someting when fonts begin to download
};
document.fonts.onloadingdone = () => {
  // do someting when fonts are loaded completely
};
document.fonts.onloadingerror = () => {
  // do someting when fonts fall into some error
};

그리고 또한 반환되는 옵션이 있습니다.Promise그리고 그것은 처리할 수 있었습니다..then함수:

document.fonts.ready
 .then(() => console.log('do someting at the final with each status'))

여기에 다른 솔루션과 다른 접근 방식이 있습니다.

저는 WebGL 텍스처를 만들기 위해 FontAwesome 4.1.0을 사용하고 있습니다.이를 통해 작은 캔버스를 사용하여 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에서도 작동할 수 있습니다.

타이머를 전혀 사용하지 않고 @font-face가 이미 로드되었는지 여부를 알 수 있는 또 다른 방법은 "스크롤" 이벤트를 사용하여 세심하게 조작된 요소의 크기가 변경되었을 때 즉각적인 이벤트를 수신하는 것입니다.

저는 어떻게 이루어지는지 블로그에 글을 썼고 Github에 도서관을 게시했습니다.

다음과 같은 것을 시도해보세요.

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

그 다음에 할 것

#text {visibility: hidden;}
#text.shown {visibility: visible;}

글꼴을 로드한 후 로드 이벤트가 발생합니다.

또는 다음을 추가할 수 있습니다.font-display: block당신의 @font페이스 선언에.

이것은 브라우저에 글꼴이 로드될 때까지 폴백 글꼴을 보이지 않게 렌더링하도록 지시합니다.display: none또는 임의의 자바스크립트 로드 폰트 탐지

활자 스크립트의 솔루션, 각도.

Angular를 사용하는 경우 이 모듈을 사용하여 글꼴을 확인할 수 있습니다.

// document.fonts.check extension
import type {} from 'css-font-loading-module';

ngOnInit() {
  this.onFontLoad();
}

public onFontLoad() {
  let myTimer = setInterval(() => {
    if (document.fonts.check('14px MyFont')) {
      console.log('Font is loaded!');
      clearInterval(myTimer);
    } else {
      console.log('Font is loading');
    }
  }, 1);
}

또한 몇몇 글꼴은 매우 무겁습니다.따라서 폰트가 로딩되는 동안 로딩화면을 추가하고 폰트가 로딩되면 로딩화면을 제거할 수 있습니다.CSS 클래스를 다음으로 변경하는 것보다 이것이 더 나은 접근법이라고 생각합니다.display: none, 사용자가 느린 인터넷을 사용할 경우 글꼴을 다운로드하는 데 3-4초 이상 걸릴 수 있기 때문입니다.

이것은 OP에 대한 완전한 해결책이 아니라 적어도 폰트 어썸이 로드되도록 보장하는 대체 접근법입니다.여기 https://wordpress.stackexchange.com/a/165358/40636 의 워드프레스 포럼에서 찾을 수 있는 원본 코드.

이것은 무관하며 글꼴 패밀리를 확인할 수 있는 글꼴과 같은 글꼴 스타일 리소스와 함께 작동합니다.조금만 더 생각해보면 더 많은 것들에 적용될 수 있을 거라 확신합니다.

<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
<script>
    (function($){
        var faSpan = $('<span class="fa" style="display:none"></span>').appendTo('body');
        if (faSpan .css('fontFamily') !== 'FontAwesome' ) {
            // Fallback Link
            $('head').append('<link href="/css/font-awesome.min.css" rel="stylesheet">');
        }
        faSpan.remove();
    })(jQuery);
</script>

아래 코드를 사용합니다.

<!DOCTYPE HTML>
<html>
    <head>
    </head>

<body>
<canvas id="canvasFont" width="40px" height="40px" style="position: absolute; display: none;"></canvas>

<script>
function IsLoadedFonts()
    {
        var Args = arguments;
        var obj = document.getElementById('canvasFont');
        var ctx = obj.getContext("2d");
        var baseFont = (/chrome/i.test(navigator.userAgent))?'tims new roman':'arial';
         //................
          function getImg(fon)
          { 
            ctx.clearRect(0, 0, (obj).width, (obj).height);
            ctx.fillStyle = 'rgba(0,0,0,1.0)';
            ctx.fillRect( 0, 0, 40, 40 );
            ctx.font = '20px '+ fon;
            ctx.textBaseline = "top";
            ctx.fillStyle = 'rgba(255,255,255,1.0)';
            ctx.fillText( '\u0630', 18, 5 );
            return ctx.getImageData( 0, 0, 40, 40 );
          };
        //..............
          for(var i1=0; i1<Args.length; i1++)
          {
            data1 = getImg(Args[i1]);
            data2 = getImg(baseFont);
            var isLoaded = false;
            //...........
            for (var i=0; i<data1.data.length; i++)
            {
                if(data1.data[i] != data2.data[i])
                    {isLoaded = true; break;}
            }
            //..........
            if(!isLoaded)
                    return false;
         }
         return true;
    };

     setTimeout(function(){alert(IsLoadedFonts('myfont'));},100);
   </script>
   </body>

많은 글꼴을 확인할 수 있습니다.

setTimeout(function(){alert(IsLoadedFonts('font1','font2','font3'));},100);

아래 코드는 오페라에서만 작동하지만 쉬운 코드입니다.

if(!document.defaultView.getComputedStyle(document.getElementById('mydiv'))['fontFamily'].match(/myfont/i))
          alert("font do not loaded ");

언급URL : https://stackoverflow.com/questions/12312323/how-to-know-if-a-font-font-face-has-already-been-loaded

반응형