web-dev-qa-db-fra.com

Passer la variable à fonctionner dans jquery AJAX callback success

J'essaie de précharger certaines images avec un appel jQuery AJAX, mais j'ai de vrais problèmes à passer une chaîne (url) à une fonction de la fonction de réussite de l'appel AJAX (si logique).

Voici mon code tel quel est:

//preloader for images on gallery pages
window.onload = function() {
    setTimeout(function() {     
        var urls = ["./img/party/"]; //just one to get started

        for ( var i = 0; i < urls.length; i++ ) {
            $.ajax({
                url: urls[i],
                success: function(data,url) {
                    $(data).find("a:contains(.jpg)").each(function(url) {                               
                        new Image().src = url + $(this).attr("href");
                    });
                }
            });
        };  
    }, 1000);
};

On peut voir ma tentative (échouée) de passage de l’URL dans l’appel .each() - url finit par prendre la valeur des entiers croissants. Vous ne savez pas vraiment pourquoi ou à quoi ces liens se rapportent, peut-être le nombre de fichiers jpg?

... de toute façon, il devrait bien sûr prendre la valeur unique de mon tableau d’URL original.

Merci pour toute aide - je semble toujours avoir un peu d'une torsion avec ces rappels.


PROGESS?

Donc, je me suis un peu mucked, prenant en compte les commentaires de @ron tornambe et @PiSquared et je suis actuellement ici:

//preloader for images on gallery pages
window.onload = function() {
    var urls = ["./img/party/","./img/wedding/","./img/wedding/tree/"];

    setTimeout(function() {
        for ( var i = 0; i < urls.length; i++ ) {
            $.ajax({
                url: urls[i],
                success: function(data) {
                    image_link(data,i);
                    function image_link(data, i) {
                        $(data).find("a:contains(.jpg)").each(function(){ 
                            console.log(i);
                            new Image().src = urls[i] + $(this).attr("href");
                        });
                    }
                }
            });
        };  
    }, 1000);       
};

J'ai essayé de mettre la image_link(data, i) ici et partout (dans chaque fonction imbriquée, etc.) mais j'obtiens le même résultat: la valeur de i n'est jamais enregistrée qu'en tant que 3. Je soupçonne que cela C’est parce que toutes les références à i pointent vers la même chose et qu’au moment où la tâche asynchrone parvient à atteindre image_link(data, i), la boucle for... est terminée avec (et a donc une valeur de 3). Inutile de dire que cela donne urls[i] Comme "non défini".

Quelques conseils (plus) pour savoir comment résoudre ce problème?

65
Jon

Puisque l'objet settings est lié à cet appel ajax, vous pouvez simplement ajouter l'indexeur en tant que propriété personnalisée, à laquelle vous pouvez ensuite accéder à l'aide de this dans le rappel de réussite:

//preloader for images on gallery pages
window.onload = function() {
    var urls = ["./img/party/","./img/wedding/","./img/wedding/tree/"];

    setTimeout(function() {
        for ( var i = 0; i < urls.length; i++ ) {
            $.ajax({
                url: urls[i],
                indexValue: i,
                success: function(data) {
                    image_link(data , this.indexValue);

                    function image_link(data, i) {
                        $(data).find("a:contains(.jpg)").each(function(){ 
                            console.log(i);
                            new Image().src = urls[i] + $(this).attr("href");
                        });
                    }
                }
            });
        };  
    }, 1000);       
};

Edit: Ajout dans un exemple mis à jour de JSFiddle, car ils semblent avoir changé le fonctionnement de leurs points de terminaison ECHO: https://jsfiddle.net/djujx97n/26 / .

Pour comprendre comment cela fonctionne, voir le champ "contexte" de l'objet ajaxSettings: http://api.jquery.com/jquery.ajax/ , plus précisément cette note:

"La référence this dans tous les rappels est l'objet de l'option de contexte passée à $ .ajax dans les paramètres; si le contexte n'est pas spécifié, il s'agit d'une référence aux paramètres Ajax eux-mêmes."

161
Paul Zaczkowski

Vous pouvez également utiliser l'attribut indexValue pour transmettre plusieurs paramètres via un objet:

var someData = "hello";

jQuery.ajax({
    url: "http://maps.google.com/maps/api/js?v=3",
    indexValue: {param1:someData, param2:"Other data 2", param3: "Other data 3"},
    dataType: "script"
}).done(function() {
    console.log(this.indexValue.param1);
    console.log(this.indexValue.param2);
    console.log(this.indexValue.param3);
}); 
7
aecavac

Essayez quelque chose comme ceci (utilisez this.url pour obtenir l'URL):

$.ajax({
    url: 'http://www.example.org',
    data: {'a':1,'b':2,'c':3},
    dataType: 'xml',
    complete : function(){
        alert(this.url)
    },
    success: function(xml){
    }
});

Tiré de ici

7
Felipe Pereira

Vous ne pouvez pas transmettre de paramètres tels que celui-ci: l'objet success est mappé sur une fonction anonyme avec un paramètre et constitue les données reçues. Créez une fonction en dehors de la boucle for qui prend (data, i) en tant que paramètres et exécutez le code ici:

function image_link(data, i) {
   $(data).find("a:contains(.jpg)").each(function(){                                
       new Image().src = url[i] + $(this).attr("href");
   }
}
...
success: function(data){
    image_link(data, i)
}
6
PiSquared

Je le fais de cette façon:

    function f(data,d){
    console.log(d);
    console.log(data);
}
$.ajax({
    url:u,
    success:function(data){ f(data,d);  }
});
3
Nassim Aouragh

Juste pour partager un problème similaire que j'avais au cas où cela pourrait aider quelqu'un, j'utilisais:

var NextSlidePage = $("bottomcontent" + Slide + ".html");

pour faire la variable pour la fonction de chargement, mais j'aurais dû utiliser:

var NextSlidePage = "bottomcontent" + Slide + ".html";

sans la $( )

Je ne sais pas pourquoi mais maintenant ça marche! Merci, enfin j'ai vu ce qui n'allait pas de ce post!

0
Alex

J'ai rencontré le problème récemment. Le problème vient quand la longueur du nom de fichier est supérieure à 20 caractères. Donc, le contournement consiste à changer la longueur de votre nom de fichier, mais l’astuce est également bonne.

$.ajaxSetup({async: false}); // passage en mode synchrone
$.ajax({
   url: pathpays,
   success: function(data) {
      //debug(data);
      $(data).find("a:contains(.png),a:contains(.jpg)").each(function() {
         var image = $(this).attr("href");
         // will loop through
         debug("Found a file: " + image);
         text +=  '<img class="arrondie" src="' + pathpays + image + '" />';
      });
      text = text + '</div>';
      //debug(text);
   }
});

Après plus d'investigation, le problème vient de la requête ajax: Mettez un œil sur le code html renvoyé par ajax:

<a href="Paris-Palais-de-la-cite%20-%20Copie.jpg">Paris-Palais-de-la-c..&gt;</a>
</td>
<td align="right">2015-09-05 09:50 </td>
<td align="right">4.3K</td>
<td>&nbsp;</td>
</tr>

Comme vous pouvez le constater, le nom du fichier est divisé après le caractère 20, de sorte que la fonction $(data).find("a:contains(.png)) ne peut pas trouver l'extension correcte.

Mais si vous vérifiez la valeur du paramètre href, il contient le nom complet du fichier.

Je ne sais pas si je peux demander à ajax de renvoyer le nom de fichier complet dans la zone de texte?

J'espère être clair

J'ai trouvé le bon test pour rassembler tous les fichiers:

$(data).find("[href$='.jpg'],[href$='.png']").each(function() {  
var image = $(this).attr("href");
0
megaten