Javascript 用于插入图像(如果存在)的ajax回调
我一直在遵循这个答案,试图编写好的异步js——但我不太明白我到底出了什么问题 我使用autocomplete从服务器请求一组特定的文件,但对于某些数据集,这些文件可能不存在,即可能有一个或最多四个文件。如果它们确实存在,我想附加.html以包含它们 除非我添加,否则图像不会加载 异步:false 到.ajax调用,这使得回调是多余的Javascript 用于插入图像(如果存在)的ajax回调,javascript,jquery,ajax,asynchronous,callback,Javascript,Jquery,Ajax,Asynchronous,Callback,我一直在遵循这个答案,试图编写好的异步js——但我不太明白我到底出了什么问题 我使用autocomplete从服务器请求一组特定的文件,但对于某些数据集,这些文件可能不存在,即可能有一个或最多四个文件。如果它们确实存在,我想附加.html以包含它们 除非我添加,否则图像不会加载 异步:false 到.ajax调用,这使得回调是多余的 for (var i = 1; i < 5; i++) { (function (counter) { // define function wi
for (var i = 1; i < 5; i++) {
(function (counter) {
// define function with the callback argument
function ajaxTest(callback) {
$.ajax({
type: "GET",
url: counter + "_1.jpg",
success: function (result) {
callback(counter);
}
});
}
// call the function
ajaxTest(function (num) {
var image_temp = '<div class="thumbnail"> <img class="img-thumbnail" src="'+ num + '_1.jpg" /> Image' + num + '</div>';
console.log(image_temp); //check readout
image_html += image_temp;
});
})(i);
}
然后image_html只包含那些存在的图像的html
$'outputcontent'.htmlooter\uHTML+图像\uHTML+外部\uHTML\uEnd
谁能解释一下我的误解吗?为什么没有填充image_html
编辑下面的“完整”代码。我使用jqueryautocomplete从stellar_comp数组中提取,然后对于那些属性为空的数组,生成html。其中包括ajax调用
$(function () {
var stellar_comp = [
{
value:'X0005-28',
data: {
set0: {
aperture:'X2105-28',
secat:'X025-18',
set:'1',
run:'r06',
continuumFilter:'J',
narrowBandFilter:'638/28',
numberOfSources:'1',
priorityCode:'1'
etc... etc ...
},
},
];
$('#autocomplete').autocomplete({
lookup: stellar_comp,
onSelect: function (suggestion) {
var path_Value = 'data/' + suggestion.value + '/';
var outer_html = '<h1>' + suggestion.value + ' </h1> <div class="container">';
var outer_html_end = '</div>';
for (var category in suggestion.data) {
if (suggestion.data.hasOwnProperty(category)) {
if (suggestion.data[category].aperture) {
summary_table_contents = '<tr> <td>' + suggestion.data[category].set + '</td> <td>' + suggestion.data[category].run + '</td> <td>' + suggestion.data[category].continuumFilter + '</td> <td>' + suggestion.data[category].narrowBandFilter + '</td> <td>' + suggestion.data[category].numberOfSources + '</td> <td>' + suggestion.data[category].priorityCode + '</td></tr> ';
summary_table += summary_table_contents;
var aperturePlot = suggestion.data[category].aperture + '_' + suggestion.data[category].run;
var seCATPlot = suggestion.data[category].secat + '_Rsub_ss_' + suggestion.data[category].run;
var aperture_match = suggestion.data[category].aperture_match;
cog = path_Plots + aperturePlot + '_cog';
sbprof = path_Plots + aperturePlot + '_sbprof';
thumb_cog = '';
thumb_cog_temp = '';
thumb_sb = '';
temp='';
for (var i = 1; i < 5; i++) {
(function (counter) {
function some_function(callback) {
$.ajax({
type: "GET",
url: cog + counter + "_1.jpg",
async: false,
success: function (result) {
callback(counter);
}
});
}
some_function(function (num) {
var thumb_cog_temp = '<div class="col-lg-3 col-sm-4 col-xs-6"> <a class="thumbnail" target="_blank" href="' + cog + num + '_1.jpg"> <img class="img-thumbnail" src="' + cog + num + '_4.jpg" /></a> <div class="caption"><h5>' + suggestion.value + ':S' + num + '</h5></div></div>';
var thumb_sb_temp = '<div class="col-lg-3 col-sm-4 col-xs-6"> <a class="thumbnail" target="_blank" href="' + sbprof + num + '_1.jpg"><img class="img-thumbnail" src="' + sbprof + num + '_4.jpg" /></a><div class="caption"><h5>' + suggestion.value + ':S' + num + ' </h5></div></div>';
console.log(num, counter);
thumb_cog += thumb_cog_temp;
thumb_sb += thumb_sb_temp;
});
})(i);
}
cog_sbprofile_row='<div class="row"><h3>C o G</h3> ' + thumb_cog + '</div><div class="row"><h3>Profiles</h3> ' + thumb_sb + '</div>';
console.log(cog_sbprofile_row);
body_html += aperture_row;
body_html += seCAT_row;
body_html += aperture_match_row;
body_html += pixel_map_row;
body_html += skyprofile_row;
body_html += cog_sbprofile_row;
body_html += '<hr>';
};
};
};
top_html += summary_table + '</tbody> </table> </div></div> <hr>';
$('#outputcontent').html(outer_html + hipass_container + top_html + body_html + outer_html_end);
}
});
});
您必须在所有ajax请求完成其工作后进行追加。首先,定义这一点:
var after = function(reqs) {
var d = $.Deferred(),
cnt = reqs.length;
if (!cnt) {
d.resolve();
}
var limit = cnt; // separate var just in case reqs are synchronous
// so it won't mess up the loop
for (var i = 0; i < limit; i++) {
reqs[i].always(function() {
cnt--;
if (!cnt) {
d.resolve();
}
});
}
return d.promise();
};
注意,我添加了return$.ajax
顺便问一下:定义ajaxTest函数的意义是什么?把所有东西都放在匿名回拨中
在此处阅读有关延迟对象和承诺的更多信息:
或者只是谷歌一下
编辑:如果顺序很重要,则只需稍微调整回调函数:
var image_html = []; // array instead of string
// some code...
var req = ajaxTest(function (num) {
// ...
image_html[counter] = image_temp;
});
// some code...
after(requests).done(function() {
image_html = image_html.join("");
$('#outputcontent').html(outer_html + image_html + outer_html_end);
});
当前的问题是由于在通过多个异步调用创建结果HTML字符串之前使用了该字符串。您需要将该操作推迟到所有加载完成,或者更改情况,使其不依赖于最终完成。无论如何,渐进加载看起来更繁忙 就我个人而言,我只需在循环时为图像插入占位符,并在加载时插入每个占位符。这样就保留了订单。您甚至可以在加载时对每个对象执行效果淡入淡出等操作:
var wrapper = "";
for (var i = 1; i < 5; i++) {
// Make a placeholder element for each image we expect
wrapper += '<div class="thumbnail" id="thumb_' + i + '">'
(function (num) {
// call the function
$.ajax({
type: "GET",
url: num + "_1.jpg",
success: function (result) {
var image_temp = '<img class="img-thumbnail" src="'+ num + '_1.jpg" /> Image' + num;
// Insert new image into unique element and fade it in
$('#thumb_'+num).append(image_temp).fadeIn();
}
});
})(i);
}
// Append all placeholders immediately - these will be appended to as each image is loaded
$('#outputcontent').html(outer_html + wrappers + outer_html_end);
更新:
正如Alnitak指出的,整个练习有点毫无意义,因为您忽略了从Ajax调用返回的结果,因此您最好放弃没有任何价值的Ajax调用,只在动态服务器端构建图像元素:您是否执行$'outputcontent';在所有异步任务完成之后?啊,我不知道-我该如何检查这一点?正如Chickencrence所建议的那样,没有代码显示会在尝试更新HTML之前等待所有异步Ajax调用完成。您需要显示代码的其余部分,以便在需要重新组织代码时提供解决方案。请注意,永远不要使用async:false。问:图像的显示顺序重要吗?它们需要按顺序加载还是按加载顺序加载?因为AJAX图像加载程序将异步加载图片,所以在将图片附加到容器DOM之前,您需要确保所有图片都已正确加载。您刚刚向新手描述了一个基于承诺的解决方案,但没有解释。你可能想详细解释一下。@TrueBlueAussie嗯,这是一个很大的话题。我添加了一些资源。希望这就足够了,我真的不想解释所有的细节。谢谢@freakish-看来我还有一天要阅读了。我想我看到了它是如何工作的。SO没有回答我的问题,但很可能图像显示顺序很重要,否则您可以在加载图像时附加每个图像,并忘记所有这些复杂性。如果顺序很重要,你的答案就不能解决整个问题。干杯。虽然是的,作为一个新手,我可能明天也会回来寻求帮助。感谢您迄今为止的投入。我对动态构建图像元素的建议有点困惑——正如我在原始帖子中所说,并不总是有四个图像。我如何知道一个图像是否存在,因此应该在不首先执行ajax请求的情况下显示?我喜欢fadeIn的想法,现在需要在包装器的末尾尝试一下,但是我已经开始工作了,我想我已经开始掌握闭包和范围了。非常感谢你的帮助@利兹·奥菲库斯:我应该解释得更清楚些。如果映像在服务器上,那么构建映像列表应该在服务器端完成,而不是在客户端完成。对本地服务器文件的所有Ajax请求都将被浏览器拉下来,这毫无意义。希望这一切都有帮助。
var wrapper = "";
for (var i = 1; i < 5; i++) {
// Make a placeholder element for each image we expect
wrapper += '<div class="thumbnail" id="thumb_' + i + '">'
(function (num) {
// call the function
$.ajax({
type: "GET",
url: num + "_1.jpg",
success: function (result) {
var image_temp = '<img class="img-thumbnail" src="'+ num + '_1.jpg" /> Image' + num;
// Insert new image into unique element and fade it in
$('#thumb_'+num).append(image_temp).fadeIn();
}
});
})(i);
}
// Append all placeholders immediately - these will be appended to as each image is loaded
$('#outputcontent').html(outer_html + wrappers + outer_html_end);