11
votes

I want to make website pages sliding smothly one to another. So I've made $('a').click(); function that checks if link is local, and if is it gets a link href and loads it to body.

$('a').click(function(){
    var href=$(this).attr('href');  
    $('body').load(href);
    return false;
});

It look nice, but my site has also a lot of js plugins included. Executing them takes a while, and .load action first shows 'unchanged by js' content, and then exectues js. It causes bad flickr of content.

Is it possible to cache new content with all the exectuion of JS, dont change old body till it's done, and when all the DOM and JS is done on NEW content, slideOut old content and slideIn new one?

edit:I think the point is not about detecting js execution but about checking if all additional files are loaded - DOM changing should be fired at the same time that $(window).load of new file would be.

[edit]----------------------------------------------------------------------

My solution for that was css code (css is loaded always before dom is build) that has cross-browser opacity 0.

.transparent{
    -moz-opacity: 0.00;
    opacity: 0.00;
    -ms-filter:"progid:DXImageTransform.Microsoft.Alpha"(Opacity=0);
    filter: progid:DXImageTransform.Microsoft.Alpha(opacity=0);
    filter:alpha(opacity=0);
}

And it prevent from bad flickr of content usually but not always. Now its possible to detect somehow that content is loaded by jQuery ajax and apply some show timeout and so on. But in fact question is still open.

To make now a little more simple example for that question:

How to begin changing DOM after $('body').load('something.php') 3000ms after clicking the link that fire .load('something.php') function? (Loading should be started instantly after clicking, but DOM changing has to be initiated later)

3
load has a callback that waits for the ajax request to complete, you can use that, and it's all in the docs, if your plugins have similar callbacks, you can use those as well, otherwise a timeout is probably the easiest solution.adeneo

3 Answers

1
votes

Maybe you should use promises and try something like this:

$('a').click(function(){
    var href=$(this).attr('href');
    $('body').hide();
    $('body').load(href, function() {
      $('body').show();
    });
});
0
votes

One thing that could help is to put your html inside some script tag with a user-defined type (or to load your html inside the script tag )

like this :

<script type="text/template" id="myTemplate">
    <div>some html</div>
</script>

the html code inside will not be understood by the Dom until you append it to the page

//... at some point
var tmp = $('#myTemplate').html();
$(body).append(tmp);

Ajos !

0
votes

Do not use .load(). That method does specifically what you're trying to avoid.

Try doing this:

  1. Load with $.get, $.post, $.ajax or whatever method suits you. This way, you get the HTML code with the scripts as an HTML string.
  2. Create a hidden div, or transparent div, or another element to put the content in. Here the trick is to make sure this div does not show until the scripts are executed. To do this, the only way is to add a last script in each page you want to load this way, with a function that removes the old content and shows the new. Being the last script, it won't execute until the other ones do, so your DOM should be ready.

Of course, if your scripts rely on something like $(document).ready(), this won't work, because this will execute immediately. Images have the same problem. They are loaded asynchronously, so you won't know when all of them are loaded, except if you attach a handler to the onload event of every image, which isn't a good idea.