web-dev-qa-db-fra.com

afficher la barre de progression lors du chargement des pages à l'aide de jquery ajax dans le site Web à page unique

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

Chaque fois qu'un utilisateur clique sur un lien de navigation, il utilise .load Pour charger le contenu de la page dans la div 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 j'affiche sur ajaxstart(), et sur la page que j'appelle, je modifie cette valeur de la barre de progression après chaque élément est chargé.

Cela fonctionne bien sur Firefox et je peux voir la barre de progression en attendant le chargement de la page, mais cela ne fonctionne pas sur Chrome ou IE.

Y a-t-il une meilleure manière de faire cela? Suis-je en train de le faire correctement ou existe-t-il une autre méthode pour le faire?

Par exemple, obtenir la taille de la page $.ajax En Ko et mettre à jour la barre de progression à la volée au fur et à mesure de la réception des données?

J'essaie de produire quelque chose de similaire à la page de chargement lors du chargement de Gmail.

33
Zalaboza

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

Pour référence, j'ai copié le code correspondant ci-dessous (vous ne seriez probablement intéressé que par la partie "Progression du téléchargement"):

$.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 c'est beaucoup de surpuissance pour un site Web d'une seule page et ne devient vraiment utile que pour les gros fichiers. De plus, les images et les supports similaires ne sont pas traités de cette manière et vous devrez surveiller le chargement des images (ou le faire vous-même via ajax) pour rendre un tel système parfait.

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

74
David Mulder

La réponse ci-dessus est correcte (vote positif). Une requête xhr personnalisée fonctionne bien, je l'ai testée avec votre code (et un fichier plus gros pour voir la progression réelle), autant la 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();
        }
    });

});
11
Laszlo R.