Cufon loaded asynchronously doesn't render in IE

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.

Answers:

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)

Answer

try calling

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

just before </body> tag closes.

Answer

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

Cufon.replace('h1', { fontFamily: 'Stag Bold' });
Cufon.now();
Answer

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>
Answer

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.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.