Skip to content Skip to sidebar Skip to footer

Is A Js Event Emitted When A Css Font Is Swapped?

Can I tell when a font has been successfully (or otherwise) loaded, and then act on that with JS? Context I'm printing a series of documents using playwright. I'm currently loading

Solution 1:

Yes you can do this with Font Face Observer which is a small @font-face to monitor the load of the font. This does not restrict you using any type of font loading.

for example

var font = new FontFaceObserver('My Family', {
  weight: 400
});

font.load().then(function () {
  console.log('Font is available');
}, function () {
  console.log('Font is not available');
});

If you want more information check out https://portalzine.de/dev/options-to-detect-when-a-font-face-has-been-loaded/

Hope that answered your question.


Solution 2:

The link in christopher-holder's answer pointed me at that useful article from Portalzine. I used the technique from their first option, i.e.

alert('Roboto loaded? ' + document.fonts.check('1em Roboto'));  // false

document.fonts.ready.then(function () {
  alert('All fonts in use by visible text have loaded.');
   alert('Roboto loaded? ' + document.fonts.check('1em Roboto'));  // true
});

document.fonts.onloadingdone = function (fontFaceSetEvent) {
   alert('onloadingdone we have ' + fontFaceSetEvent.fontfaces.length + ' font faces loaded');
};

and moved the logic to the Playwright script using page.waitForFunction like this:

await page.goto(
  "file:///" + path.resolve(htmlFilename),
  (waitUntil = "networkidle")
);
await page.waitForFunction(() => document.fonts.check("1em Raleway"));

This waits for the page to finish loading, and for the network to be quiet for ½ a second, and then checks if the font is loaded.

FontFaceObserver looks nice, but this approach keeps the printing logic in the playwright script and doesn't touch the document itself, which feels cleaner.

This might be belt and braces, I'll update this answer once I've tested it more thoroughly.


Solution 3:

Here's a piece of JS code that I'm using to re-adjust the scroll position to adjust for :target scroll-margin and web fonts that differ from fallback fonts:

if (location.hash)
{
    var targetElement = document.getElementById(location.hash.substring(1));
    if (targetElement && targetElement.scrollIntoView)
    {
        // scroll to correct position immediately
        targetElement.scrollIntoView({block:"start", behavior:"auto"});

        // Note that because the page might be rendered before
        // web fonts are ready and web fonts may/will cause
        // layout shift, we'll need to re-adjust the scroll
        // position when fonts are ready:
        try
        {
            var fontsReady = document.fonts.ready;
            fontsReady.then(function ()
            {
                console.log('Font loading complete');
                // process full event loop and re-adjust the scroll:
                window.setTimeout(function ()
                {
                    targetElement.scrollIntoView({block:"nearest", behavior:"smooth"});
                }, 0);
            });
        }
        catch (e)
        {
            console && console.error && console.error(e);
            console && console.log && console.log("This browser doesn't support observing font loading, scroll position may be incorrect.");
        }
    }
}

Depending on your use case and expected event timing both calls to scrollIntoView() could use behavior:"auto" or behavior:"smooth". Also note that the user may have scrolled the viewport between rendering the content with fallback fonts and web font loading completing so you may want to add additional code to listen for scroll events and avoid scrolling anything when web fonts are swapped in if user has already scrolled to another position.


Post a Comment for "Is A Js Event Emitted When A Css Font Is Swapped?"