0

I made a slideshow using the slide template at "HTML5Rocks!", and modified it to include some interactive google charts.

Unfortunately, initially the HTML5 slide template hides all slides but the current, two following slides, and two preceeding slides (this is in the css default for a slide: .slides > article { display : none; }). My interactive figures are slides (i.e. articles) containing iframes with google charts inside. Unfortunately, slides that are first rendered display:none have some sort of bounding box issue with google charts: when the slide is finally un-hidden, the chart is compressed and does not have interactive effects.

I was able to work around this by starting the default slide (i.e. not simply the current slide and its neighbors, but all slides) with display:block. Then, when you change slides, I actively hide the non-current and non-neighboring ones. Now all charts render properly, but at the start of the presentation, it shows the final slide (because all are drawn and it is drawn last!).

I wanted to polish this around by adding an event that, after everything is loaded (i.e. CPU-intensive AJAX calls within an iframe are finished running), the non-current and non-neighboring slides are hidden.

To do this, I need to trigger a callback event after everything is loaded and the browser is ready (including AJAX calls within iframes):

I tried the following, but it triggers too early, before the AJAX callbacks in my iframes have finished:

jQuery(window).load( function() { /* some code to hide the non-current and non-neighboring slides */ } );

So the non-current and non-neighboring slides are hidden before the charts are drawn, and when those chart slides are un-hidden, they are warped and ruined. I don't believe I can trigger my event with the AJAX calls, because they there are multiple (from multiple slides) that I want to finish.

So that's the framing story. Here's what I want to know: Is there an event that triggers after everything is loaded and the browser is completely ready?

Thanks a lot for your help.

user
  • 7,123
  • 7
  • 48
  • 90

1 Answers1

2

There is no built in JavaScript event that triggers after all AJAX calls within iframes on the page have completed.

There are a couple examples on handling iframe events here:

Outside of that, you will need to keep track of each of your AJAX calls, and check if all of them have successfully completed after each individual completion. It would also probably be a good idea to set a timeout in case one of them fails or doesn't return an error.

Here's a rough example.

// Keep track of your ajax content.
var ajaxComplete1 = false;
var ajaxComplete2 = false;

var timeoutInterval; // For timeouts.

// Check if everything is complete.
function checkPageComplete() {
    if (ajaxComplete1 && ajaxComplete2) {
        clearInterval(timeoutInterval); // Clear timeout.
        // Everything has loaded, do your initialization.
    }
}

// Wait for the main page to load.
$(window).load(function() {

    // Wait 30 seconds for dynamic content to load.
    timeoutInterval = setInterval(function() {
        clearInterval(timeoutInterval);
        // Handle timeout.
    }, 30000);

    // Load the first content.
    $.ajax({
        url: 'someurl',
        success: function(data, textStatus, jqXHR) {
            ajaxComplete1 = true;
            checkPageComplete();
        },
        error: function(jqXHR, textStatus, errorThrown) {
            // Handle error.
        }
    });

    // Load the second content.
    $.ajax({
        url: 'anotherurl',
        success: function(data, textStatus, jqXHR) {
            ajaxComplete2 = true;
            checkPageComplete();
        },
        error: function(jqXHR, textStatus, errorThrown) {
            // Handle error.
        }
    });


});
Community
  • 1
  • 1
Craig
  • 691
  • 4
  • 20
  • +1, but your setInterval can't possibly have any effect - it only does anything when both AJAX requests have successfully completed, in which case `do your initialization` will have happened anyway. – RichieHindle Jun 10 '13 at 19:14
  • Not exactly. The actual timeout would be handled on its own, and will only fire if 30 seconds pass before the AJAX requests complete. It is cleared out and does not fire if both AJAX requests successfully complete. – Craig Jun 10 '13 at 19:16
  • Sorry, my fault for misreading it - your intention (which is perfectly clear now that I look at it again) was for `// Handle timeout` to do whatever needs to be done if the AJAX requests don't complete. Sorry for the noise! – RichieHindle Jun 10 '13 at 19:22
  • Great idea. I used a global array attached to `window.` and `parent.` in the `iframe`s. I probe every 10 seconds for the array to be the correct length and be full of only `true` (at the start of every AJAX call I `push(false)` and then change that index to `true` upon completion). Thanks! – user Jun 10 '13 at 20:50