在 jquery AJAX 成功回调中将变量传递给函数

我试图用一个 jQuery AJAX 调用预加载一些图像,但是在将一个(url)字符串传递到 AJAX 调用的成功函数中的一个函数中时遇到了实际问题(如果这有意义的话)。

以下是我的原则:

//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);
};

我们可以看到我尝试将 url 传递到 .each()调用中(失败了)-url最终会得到增加的整数值。不确定为什么或者这些与什么有关,也许是 jpg 文件的数量?

... 不管怎样,它当然应该接受原始 urls 数组中的单个值。

谢谢你的帮助——我似乎总是对这些复试有点纠结。


进展?

所以,我四处闲逛了一下,留意了@ron tornambe 和@PiSquared 的评论,现在我在这里:

//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);
};

我试着把 image_link(data, i)放在这里和任何地方(在每个嵌套函数中等等) ,但是我得到了相同的结果: i的值只被记录为3。我怀疑这是因为所有对 i的引用都指向同一个东西,当异步任务实际到达 image_link(data, i)时,for...循环就结束了(因此值为3)。不用说,这给了 urls[i]“未定义”。

还有什么(更多)技巧可以让我避开这个问题吗?

146078 次浏览

Try something like this (use this.url to get the url):

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

Taken from here

You can't pass parameters like this - the success object maps to an anonymous function with one parameter and that's the received data. Create a function outside of the for loop which takes (data, i) as parameters and perform the code there:

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)
}

Just to share a similar problem I had in case it might help some one, I was using:

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

to make the variable for the load function, But I should have used:

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

without the $( )

Don't know why but now it works! Thanks, finally i saw what was going wrong from this post!

Since the settings object is tied to that ajax call, you can simply add in the indexer as a custom property, which you can then access using this in the success callback:

//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: Adding in an updated JSFiddle example, as they seem to have changed how their ECHO endpoints work: https://jsfiddle.net/djujx97n/26/.

To understand how this works see the "context" field on the ajaxSettings object: http://api.jquery.com/jquery.ajax/, specifically this note:

"The this reference within all callbacks is the object in the context option passed to $.ajax in the settings; if context is not specified, this is a reference to the Ajax settings themselves."

I've meet the probleme recently. The trouble is coming when the filename lenght is greather than 20 characters. So the bypass is to change your filename length, but the trick is also a good one.

$.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);
}
});

After more investigation the trouble is coming from ajax request: Put an eye to the html code returned by 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>

As you can see the filename is splitted after the character 20, so the $(data).find("a:contains(.png)) is not able to find the correct extention.

But if you check the value of the href parameter it contents the fullname of the file.

I dont know if I can to ask to ajax to return the full filename in the text area?

Hope to be clear

I've found the right test to gather all files:

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

You can also use indexValue attribute for passing multiple parameters via object:

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);
});

I'm doing it this way:

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