How to know when font-face has been applied
I am currently building a corporate website for a customer that uses custom fonts extensively.
On jQuerys DOM-ready I am doing placement calculations to figure out where some pop-up menus with dynamic width and height should be placed based on their dynamic contents.
These calculations fail, since DOM-ready is fired before font-face is applied, and thus widths and heights are incorrect.
Right no开发者_开发技巧w (for the prototype) i am doing the calculations 500ms after DOM-ready to alleviate this problem, but this can't go into production for obvious reasons.
The problem has been observed in latest Firefox and chrome. IE 8 doesn't seem to have the problem, but then DOM-ready fires fairly late, so the delay is kind of built in I guess :)
Waiting for the load event is not an option, so my question to you is this:
Is there a reliable cross-browser way to detect when font-face has been applied?
I found a solution after wondering why IE doesn't suffer from this problem.
Firefox and Chrome/Safari triggers the DOMContentLoaded
event before font-face is applied, thus causing the problem.
The solution is to not listen for DOMContentLoaded
but instead go oldschool and listen to onreadystatechange
and wait until the document.readyState === 'complete'
which is always triggered after font-face is applied (as far as I can tell by my tests) - which is of course what always happens in IE since it doesn't support DOMContentLoaded
.
So basically you can roll-your-own event in jQuery called fontfaceapplied
- maybe it should be built in ;)
document.onreadystatechange = function() {
if (document.readyState === 'complete')
$(document).trigger('fontfaceapplied');
};
Funny fact: Opera does it right and waits to trigger DOMContentLoaded
until font-face is applied.
ES6 update:
The question post is for many years ago which the IEs version 8 and earlier were still alive and even Ecmascript version 6 was not released, but now you can write callbacks on document.fonts
events. eg:
document.fonts.onloadingdone = () => {
// do something after all fonts are loaded
};
For more information see this post.
Setting the function to trigger after a timeout of 200ms solves this issue when using Google Fonts.
There's a noticeable jump, but there usually is for equal heights stuff, for the purists this might not be perfect but it works cross browser.
精彩评论