views:

87

answers:

3

I am using jQuery UI to build tabs on my page. That works well until I add this following piece of code.

$(function () {
    $('#tabs').children("div").each(function (index) {
        $('#tabs').tabs('load', index);
    });
});

I'm trying to preload the tabs. What is interesting, is that if i run this through Firebug and put a breakpoint in that piece of code and step through, the code works perfectly. Otherwise the tabs are rendered, but the content within the tabs is not. This issue has been driving me crazy! Can anyone help?

A: 

Not sure but this line looks problematic to me:

$('#tabs').tabs('load', index);

I believe you are going to have more than one tab but you are using id #tab which should be used once per element per page. Try using a class for those tabs instead:

$('.tabs').tabs('load', index);
Sarfraz
A: 

Are there any console functions being used in the remote content that is loaded? One change that is obvious when Firebug is enabled vs when it is not, is the addition of all these console.* functions to the global object. So if you have for example a log statement:

console.log("hello")
alert("world");

this will only alert "world" if Firebug is enabled, otherwise a call to console.log will throw a ReferenceError error and none of the subsequent code will run resulting in no alerts being shown.

One other possibility I can imagine has to do with asynchronous loading of content. When you set breakpoints, it adds time to the remote content that is loading while you are waiting at the breakpoint. By the time you move forward that content is potentially loaded and execution proceeds as normal. However, when there are no breakpoints the script will continue executing without stops and may break. This, of course, is just a theory.

Anurag
I don't have any console.log statements in my script (remove them after I found another answer where this caused problems), but I definitely was thinking that your theory is right. Just wasn't sure how to solve it.
JasCav
+1  A: 

If you look at the jQuery UI source for tabs the problem shows itself pretty fast, here's the start of what happens when you call that load function:

load: function(index) {
  index = this._getIndex(index);
  var self = this, o = this.options, a = this.anchors.eq(index)[0], 
             url = $.data(a, 'load.tabs');
  this.abort();  //uh oh

When you call load on a tab, the first thing it does is kill any other tabs running an AJAX call. So if you look at your page it is pre-loading the tabs, but only the last tab, because in a quick loop, each tab kills the previous one's AJAX request.

I think you'll want to re-visit how you're doing this as a whole, since the AJAX model is intended to load from the anchors (the <div> elements shouldn't be there at all) I'm not sure exactly how your markup looks here.

You have 2 options though, you can either do the AJAX loads yourself (better IMO), or use the built-in but do it sequentially, like this:

$("#tabs").tabs({
  load: function(event, ui) {
    if(ui.index != $("#tabs a").length - 1) //not on the last tab
      $(this).tabs('load', ui.index + 1);   //load the next tab
  }
}).tabs('load', 0);                         //kick off the first

I don't have a good environment to test the above, but we're basically using the load event which fires when one tab finishes loading, then we start the next (so we never abort the one before in the loop). This is much slower, since we're doing serial and not parallel requests...this is why for performance I recommend you make the .load() call yourself outside anything .tabs() offers.

Nick Craver
Excellent help! Thank you, Nick. I think I understand what you are saying about AJAX loading from the anchors, but, being new to AJAX, if you could flesh that out a bit more for me, I would greatly appreciate it.
JasCav