jchwebdev
jchwebdev

Reputation: 5450

Async Javascript causes JS error function does not exist

I have a jQuery script that I added an ASYNC attribute to. It seems to work OK in Firefox, but intermittently fails in Chrome and IE.

The PHP for loading adding the async attrib. This works fine:

function add_async_attribute($tag, $handle) {
   if ( substr($handle,0,3) !== 'jch' )
      return $tag;
   return str_replace( ' src', ' async="async" src', $tag );
 }

 add_filter('script_loader_tag', 'add_async_attribute', 10, 2);

The JS file that causes a problem with the ASYNC attrib:

jQuery(document).ready(function($) {    
    jQuery('.home #intro_reel').jchTextReel( {fadeTime: 16000} );       
});

jQuery.fn.extend({

    jchTextReel: function(options) {                
        var defaults = {
                fadeTime: 10000,
                mouseOverColor : '#000000',
                mouseOutColor : '#ffffff'
        }

        var options =  jQuery.extend(defaults, options);

          return this.each(function() {
          var o = options;      

          ....etc....

Chrome shows an error 'jchTextReel is not a function'.

Again, removing the ASYNC attrib makes the script work OK again. OR, if I hit F5 to reload, the script seems to work.

Why? How do I fix?

Upvotes: 1

Views: 858

Answers (3)

Sufian Saory
Sufian Saory

Reputation: 892

your file is being loaded asynchronously. when it is loaded, document ready is already triggered. that's why your top document ready is being executed immediately and calling jchTextReel which is not defined yet. to resolve it you need to first define jchTextReel then put the call. it seems firefox is ignoring async and loading the file synchronously but ie & chrome honoring async.

Upvotes: 1

Alex Kudryashev
Alex Kudryashev

Reputation: 9460

In your case two approaches are possible.
1. Add async="async" and put jQuery('.home #intro_reel').jchTextReel( {fadeTime: 16000} ); to the end of your file (.js)
2. Load the script from .ready handler. async attribute is not required in this case.

$(document).ready(function($) {  
    $.getScript('path/to/script', function(){
       jQuery('.home #intro_reel').jchTextReel( {fadeTime: 16000} ); 
    });
});

Upvotes: 0

Dave Romsey
Dave Romsey

Reputation: 528

async and defer are two separate boolean attributes. Doing async="defer" will set async to true, but defer is not set, so my guess is that sometimes the script is executing too soon. Here is a tweaked version of add_async_attribute() with distinct async and defer attributes:

function add_async_attribute($tag, $handle) {
    if ( substr($handle,0,3) !== 'jch' )
        return $tag;
    return str_replace( ' src', ' async defer src', $tag );
}

add_filter('script_loader_tag', 'add_async_attribute', 10, 2);

Also, it's not shown in the original code posted, but the script that is being run uses jQuery, so jquery should be specified as a dependency for that script.

Upvotes: 0

Related Questions