Affiche la barre de progression pendant le chargement des pages à l'aide de jquery ajax dans un site Web en une seule page

J'ai une page de base avec une barre de navigation en haut et un corps d'enveloppe.

Chaque fois qu'un utilisateur clique sur un lien de navigation, il utilise .load pour charger le contenu de la page dans la .load wrapper.

 $(this).ajaxStart(function(){$('.progressbar .bar').css('width','5%');$('.progressbar').fadeIn();}); $(this).ajaxEnd(function(){$('progressbar').hide();}); $('.ajaxspl').on('click',function(e){ e.preventDefault(); var url=$(this).data('url'), wrap=$('body #wrap'); //clean the wrapper wrap.slideUp().html(''); //load page into wrapper wrap.load(url,function(){wrap.slideDown();}); }); 

Exemple de valeur de retour de .load :

 <div> ...content </div> <script>$('.progressbar .bar').css('width','30%');</script> <link href="/assets/css/datepicker.css" rel="stylesheet" /> <script>$('.progressbar .bar').css('width','60%');</script> <link href="/assets/css/main.css" rel="stylesheet" /> <script>$('.progressbar .bar').css('width','90%');</script> <script>//blah blah</script> 

Comme vous pouvez le voir, j'ai une barre de progression Bootstrap que je montre sur ajaxstart() , et sur la page que j'appelle, je modifie cette valeur de la barre de progression après chaque chargement.

Cela fonctionne bien sur Firefox et je peux voir la barre de progression en attendant que la page soit chargée, mais cela ne fonctionne pas sur Chrome ou IE.

Y a-t-il une meilleure manière de faire cela? Est-ce que je le fais correctement ou existe-t-il une autre méthode pour le faire?

Par exemple, obtenir la taille de la page $.ajax en kb et mettre à jour la barre de progression à la volée à mesure que les données sont reçues?

J'essaie de produire quelque chose de similaire à la page Chargement lorsque Gmail est en cours de chargement.

Permettez-moi de vous référer à cette page , il décrit comment vous pouvez ajouter un auditeur d' progress event à l'objet xhr (qui ne fonctionne que dans ces navigateurs , dans les navigateurs plus anciens, vous avez simplement confiance sur la même base que vous utilisez actuellement) dans jquery .

Pour référence, j'ai copié le code pertinent ci-dessous (vous ne seriez intéressé que par la partie «Télécharger la progression»):

 $.ajax({ xhr: function() { var xhr = new window.XMLHttpRequest(); //Upload progress xhr.upload.addEventListener("progress", function(evt){ if (evt.lengthComputable) { var percentComplete = evt.loaded / evt.total; //Do something with upload progress console.log(percentComplete); } }, false); //Download progress xhr.addEventListener("progress", function(evt){ if (evt.lengthComputable) { var percentComplete = evt.loaded / evt.total; //Do something with download progress console.log(percentComplete); } }, false); return xhr; }, type: 'POST', url: "/", data: {}, success: function(data){ //Do something success-ish } }); 

Permettez-moi de dire cependant que cela coûte énormément pour un site Web de page unique et ne devient vraiment utile que pour les fichiers volumineux. En outre, les images et les médias similaires ne sont pas gérés de cette façon et vous devriez surveiller le chargement des images (ou faites-le vous-même via ajax) pour rendre ce système parfait.

Voici un jSFiddle montrant cela en action: http://jsfiddle.net/vg389mnv/1/

La réponse ci-dessus est correcte (upvoted). Une requête xhr personnalisée fonctionne bien, je l'ai testé avec votre code (et un fichier plus grand pour voir la progression réelle), peut aussi bien le copier ici:

 $('.ajaxspl').on('click',function(e){ e.preventDefault(); var url=$(this).data('url'), wrap=$('body #wrap'); //clean the wrapper wrap.slideUp().html(''); //load page into wrapper console.log('starting ajax request'); $.ajax({ xhr: function() { var xhr = new window.XMLHttpRequest(); xhr.addEventListener('progress', function(e) { if (e.lengthComputable) { $('.progressbar .bar').css('width', '' + (100 * e.loaded / e.total) + '%'); } }); return xhr; }, type: 'POST', url: url, data: {}, complete: function(response, status, xhr) { console.log(response) wrap.html(response.responseText); wrap.slideDown(); } }); });