Problem with queued events (Ajax load) in my plugin

Problem with queued events (Ajax load) in my plugin

Here is the code (my questions at the bottom):

  1. ;(function($) {
  2.   $.fn.tq_contentslider = function(o)    {
  3.         var options = $.extend({}, $.fn.tq_contentslider.defaults, o);
  4.        
  5.         return this.each(function() {
  6.             //get metadata if plugin available
  7.             var opts = $.metadata ? $.extend(options, $.metadata.get(this)): options;
  8.             //set initial menu and content display on page load
  9.             var $menubar = $(this);
  10.             var $container = $('#'+opts.container_id);
  11.             var hash = '';
  12.             path = window.location.href.split('/');
  13.             hash = path[path.length - 1].split('.')[0];
  14.             if(hash.length && $('li a#tq_menu_'+hash, $menubar).length) {
  15.                 $('li a#tq_menu_'+hash, $menubar).addClass('current');
  16.                 $('div#'+opts.container_id+'_'+hash, $container).addClass('current');
  17.             } else {
  18.                 $('li a:first', $menubar).addClass('current');
  19.                 $('div:first', $container).addClass('current');
  20.             }
  21.             //set events for menu elements
  22.             $('li a', $menubar)
  23.                 .click(function() {
  24.                     if(!$(this).is('.current') && !$container.is(':animated')) {
  25.                         var $this = $(this);
  26.                         hash = $this.attr('href').split('#')[1];
  27.                         $content = $('div#'+opts.container_id+'_'+hash);
  28.                         //onStart callback
  29.                         opts.onStart($this, $container, $content, hash, opts);
  30.                         //remove and set menu current classes
  31.                         $('li a.current', $menubar).removeClass('current').css({backgroundPosition: '0px 0px'});
  32.                         $this.addClass('current').css({backgroundPosition: '0px -'+(opts.menu_height * (opts.menu_sprites - 1))+'px'});
  33.                         //animate and set content current classes
  34.                         $container.animate({height: '5px'}, opts.speed, opts.easing, function() {
  35.                             $('div.current', $container).removeClass('current');
  36.                             //onHide callback
  37.                             opts.onHide($this, $container, $content, hash, opts);
  38.                             $container.animate({height: $content.addClass('current').outerHeight()}, opts.speed, opts.easing, function() {
  39.                               //onEnd callback
  40.                               opts.onEnd($this, $container, $content, hash, opts);
  41.                             });
  42.                         });
  43.                     }
  44.                     return false;
  45.                 })
  46.                 .mouseover(function() {
  47.                     if(!$(this).is('.current')) {
  48.                         $(this).css({backgroundPosition: '0px -'+(opts.menu_sprites > 1 ? opts.menu_height : 0)+'px'});
  49.                     }
  50.                 })
  51.                 .mouseout(function() {
  52.                     if(!$(this).is('.current')) {
  53.                         $(this).css({backgroundPosition: '0px 0px'});
  54.                     }
  55.                 });
  56.         });
  57.     }
  58. })(jQuery);
  59. $.fn.tq_contentslider.defaults = {
  60.     container_id: 'tq_content',
  61.     speed: 1000,
  62.     menu_sprites: 3,
  63.     menu_height: 55,
  64.     easing: 'swing',
  65.     onStart: function() {},
  66.     onHide: function() {},
  67.     onEnd: function() {}
  68. };
  69. function sliderOnHide($menu, $container, $content, hash, opts) {
  70.     //check whether to perform ajax
  71.     if($content.html().length < 10 || $('h1 cufontext:first', $content).html() == 'Error') {
  72.         $content.load('ajax_main.php', {hash: hash}, function(resp, status, xhr) {
  73.             if(status == 'error') {
  74.                 $content.html('<h1>Error</h1><p>A network error has occurred, likely due to network congestion. The content could not be loaded. Please try again.<p>');
  75.                 $menu.removeClass('current').css({backgroundPosition: '0px 0px'});
  76.             }
  77.             Cufon.replace('div#'+opts.container_id+'_'+hash+' h1');
  78.         });
  79.     }
  80. }

The problem is lines 37 and 38. opts.onHide calls the callback function sliderOnHide (which performs an Ajax load call) at the bottom of the listing. The problem is that line 38 starts executing before line 37 completes, thus line 38 cannot calculate a proper outerHeight.

Any suggestions on how to ensure line 37 completes before line 38 begins too do so?

(If you have any other tips for the rest of the code, feel free to pass it on. This is my first plugin. Using it to get a feel for jQuery.)

Thanks,
M.