Cufon loaded asynchronously doesn't render in IE

4.5k views Asked by At

I'm creating a site which uses Cufon and is particularly heavy in terms of page-weight due to a large amount of Javascript. Therefore I'm trying to load in the script asynchronously with head.js ( http://headjs.com/ ) like so:

head.js("http://ajax.microsoft.com/ajax/jquery/jquery-1.4.2.min.js", function() {
 head.js("/js/libs/cufon-yui.js", function() {
    head.js("/js/shared/Stag_Bold_700.font.js" , function() {
            Cufon.replace('h1', { fontFamily: 'Stag Bold' });
    });
 });
});

So Jquery is downloaded first, the subsequent cufon lib file and cufon font are downloaded in sequence and then Cufon is finally called to replace the H1. Obviously, this is a trimmed down example with fewer replacements but this still doesn't work when just attempting to replace the H1.

The problem is that ONLY in Internet Explorer (6/7/8), the text is not replaced but I can see that Cufon has definitely been called. I can ascertain this because the tag has the class "cufon-active cufon-ready" added to it. When I inspect the markup using the IE Developer toolbar, the cufon/cufoncanvas tags are there inside the selected elements but are, for want of a better word, invisible.

In IE9, the script behaves as intended similar to Chrome and Firefox. I have tried adjusting the Cufon drawing engine and have updated to the latest 1.09i version for good measure. If I move the Cufon calling statements to the document ready event instead of loading asynchronously, it works but I am trying to optimize page load and my site will be using a number of Cufon fonts as well as many other JS plug-ins. I've also tried using both labs.js and head.js to load the appropriate files asynchronously.

5

There are 5 answers

2
CameraSchoolDropout On BEST ANSWER

I had the same problem - I addressed this by using the browser detection of head.js to do the following:

if (head.browser.mozilla || head.browser.webkit || head.browser.opera ||
        (head.browser.ie && (head.browser.version == '9.0'))) {
        head.js('script/jquery.min.js',
                'script/cufon.js', function () {
                    head.js('script/bebas_neue_400.font.js', function () {
                        Cufon.replace('h1', {
                            textShadow: '1px 1px rgba(0, 0, 0, 0.2)'
                        }).now();
                        // or a head.js('scripts/file.with.cufon.replacement.js');
                    });
                });
            } else {
        // here we load scripts depending on GZIP support for this browser
        document.write('\x3Cscript type="text/javascript" src="script/jquery.min.js">\x3C/script>');
        document.write('\x3Cscript type="text/javascript" src="script/cufon.js">\x3C/script>');
        document.write('\x3Cscript type="text/javascript" src="script/bebas_neue_400.font.js">\x3C/script>');
        document.write('\x3Cscript type="text/javascript" src="script/file.with.cufon.replacement.js">\x3C/script>');            
    }

You could also use conditional comments (I didn't because I am also doing GZIP support detection in JavaScript and needed to adjust the scripts which are loaded dynamically.)

It's a hack, but should be useful enough until it's addressed within the library itself.

(I have also posted GIST with a more complete example here)

1
Dev On

try calling

 <script type="text/javascript"> Cufon.now(); </script>

just before </body> tag closes.

0
matthewgregory On

Try adding Cufon.now() after the Cufon.replace call, like so:

Cufon.replace('h1', { fontFamily: 'Stag Bold' });
Cufon.now();
1
Kevin C. On

I solved this in a way similar to CameraSchoolDropout's approach, except instead of using Document.write, I'm using IE conditional tags, and YepNope.js.

This issue on github says that they had problems using document.createElement('script'), and I just felt better using IE conditionals.

You can see an example page that I created at http://epraxadev.com/yepnope/

<head>

<style type="text/css">
#txt    { visibility:hidden; }
</style>

<!--[if lte IE 8]>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<script src="js/cufon-yui.js"></script>
<script src="js/adventor.cufon.js"></script>
<![endif]-->

<script src="js/modernizr.custom.js"></script>
<script>
yepnope([{
    test: window.jQuery,
    nope: {
        'yJ': '//ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js',
        'yCufon': 'js/cufon-yui.js',
        'yFont': 'js/museo.font.js'
    },
    callback: {
        'yJ': function(){
            console.log("YepNope loaded jQuery! This isn't IE!");
        }
    },
    complete: function() {
        console.log('All browsers, including IE, will show this');

        Cufon.replace('h1');

        $(document).ready(function(){
            $('#txt').css('visibility', 'visible');
        });
    }
}]);
</script>

<noscript>
    <style type="text/css">
    #txt { visibility:visible; }
    </style>
</noscript>

</head>
0
Miller Medeiros On

For now just load jQuery and Cufón using regular <script> tags and load the subsequent files using a script loader.

Using document.write is a bad approach since it will only work if the script is loaded/executed before DOMReady and using browser sniffing to do it isn't a good approach either since it can give false results.

Conditional comments aren't a good solution either because you may need to update the scripts in the future and you will have to remember to update it in 2 different places which is bad for maintainability.

Follow this issue on GitHub to know when the bug is fixed.