问题
看起来像一个比赛条件。请记住,AJAX 是异步运行的,因此,在success
成功接收到 AJAX 响应后,处理程序将在将来的某个时间运行。在分派 AJAX 请求时,脚本的其余部分正在执行。具体来说:
$("body").append(html + "</div>");
在成功处理程序被触发之前运行;意味着您的html
变量还没有更新。
解决方案 1
移动
$("body").append(html + "</div>");
在您的success
处理程序中。
html += "Closing tags from the header";
afterAjax();
// console.log(html); returns correct information here
$("body").append(html + "</div>");
},
解决方案 2 ($.ajaxStop)
确保在拨打电话之前注册您的处理程序$.ajax()
。这将确保您的 AJAX 请求不会在您为.ajaxStop
.
function loadFeeds() {
html = "";
$.ajaxStop(function(){$(document.body).append(html + "</div>);
$.each(pages, function(index, page) {
$(".pages").append("<a class=\"pagename\" href=\"#" + page[0] + "\">" + page[0] + "</a>");
html = "<div class=\"page\" id=\"" + page[0] + "\">";
...
}
解决方案 3(来自您的 jsLint+Deffereds)
此示例取自您完全正常工作的 jsLint 链接。此代码获取$.ajax
循环中创建的所有请求,并将它们存储在一个数组中,以便稍后应用于$.when().done()
调用。$.when()
将检查$.ajax
应用到它的每个请求,并在完成后调用$.done()
. 每个$.ajax
请求都将其响应存储在html = []
定义在开头的数组中$.ready()
。当延迟检查 ( $.when()
) 看到所有$.ajax
请求都已完成时,我们然后加入数组 ( array.join('')
) 以创建 1 个大 HTML 块并将其附加到文档中。然后我们调用你的afterAjax()
函数。
$(document).ready(function () {
var html = [];
var feeds = ["http://pulsesubscriber.appspot.com/items?feed=http://feeds.gawker.com/lifehacker/vip&jsonp=?",
"http://pulsesubscriber.appspot.com/items?feed=http://allthingsd.com/feed&jsonp=?",
"http://pulsesubscriber.appspot.com/items?feed=http://feeds.cnet.com/latestnews/pulse&jsonp=?"];
loadFeeds(feeds);
function loadFeeds(feeds) {
var requests = [];
$.each(feeds, function(index, feedUrl) {
requests.push($.ajax({
type: "GET",
url: feedUrl,
processData : true,
data: {
tagmode: "any"
},
jsonp: "jsonp",
dataType: "jsonp",
success: function(data) {
var feedElements = "<header class=\"feed-title\"><div class=\"feed-title-content\"><span class=\"feed-title-text\">" +
data.responseData.feed.title +
"</span></div></header><section class=\"row\"><div class=\"scroll-left\"></div><div class=\"row-scroll\">";
$.each(data.responseData.feed.entries, function(index,entry) {
var feedElements = '';
if (entry.image_urls.length === 0) {
feedElements += "<div class=\"tile no-img\"><title class=\"tile-title no-img\">" +
entry.title +
"</title><hr class=\"no-img hr\" /><span class=\"no-img excerpt\">" +
entry.contentSnippet +
"</span><div class=\"tile-modal\"><div class=\"article-wrapper\">\r\n<div class=\"article-header\">\r\n<a class=\"article-title-link\" target=\"_blank\" href=\"" +
entry.link +
"\">\r\n<h1 class=\"article-title\">" +
entry.title +
"</h1>\r\n</a>\r\n<h2 class=\"article-byline\">By " +
entry.author +
": " +
data.responseData.feed.title +
"</h2>\r\n</div>\r\n<hr class=\"article-hr\"/>\r\n<div class=\"article-content\">" +
entry.content +
"\r\n<a class=\"read-more\" target=\"_blank\" href=\"" +
entry.link +
"\">Read More...</a>\r\n</div>\r\n</div></div></div>\r\n";
}
else {
feedElements += "<div class=\"tile\"><img class=\"tile-image\" src=\"" +
entry.image_urls[0] +
"\" /><title class=\"tile-title\">" +
entry.title +
"</title><div class=\"tile-modal\"><div class=\"article-wrapper\">\r\n<div class=\"article-header\">\r\n<a class=\"article-title-link\" target=\"_blank\" href=\"" +
entry.link +
"\">\r\n<h1 class=\"article-title\">" +
entry.title +
"</h1>\r\n</a>\r\n<h2 class=\"article-byline\">By " +
entry.author +
": " +
data.responseData.feed.title +
"</h2>\r\n</div>\r\n<hr class=\"article-hr\"/>\r\n<div class=\"article-content\">" +
entry.content +
"\r\n<a class=\"read-more\" target=\"_blank\" href=\"" +
entry.link +
"\">Read More...</a>\r\n</div>\r\n</div></div></div>\r\n";
}
html.push(feedElements);
console.log('updated elements');
if(index == 34 ){
return false;
}
});
},
error: function(x,y,z) {
console.log(x.responseText);
}
}));
});
$.when.apply(this,requests).done(function(){
console.log('when!');
console.log(html);
$(document.body).append($(html.join('')));
afterAjax();
});
}
$("#refresh-all").click(function(){
$("body > header, body > section").remove();
$("body").removeClass("active");
loadFeeds();
});
function afterAjax() {
$(".page:first").addClass("active");
$(".tile").click(function(){
if ($(".tile-modal.tile-modal-active").length) {
$(".tile-modal.tile-modal-active").removeClass("tile-modal-active");
$(this).children(".tile-modal").addClass("tile-modal-active");
}
else {
$(this).children(".tile-modal").addClass("tile-modal-active");
$("body").addClass("active");
}
});
$(".scroll-left").hover(function(){
$(this).parent().animate({scrollLeft: 0}, 7000);
}, function() {
$(this).parent().stop();
});
$(".scroll-right").hover(function(){
$(this).parent().animate({scrollLeft: $(this).siblings(".row-scroll").width()}, 7000);
}, function() {
$(this).parent().stop();
});
}
});
如果您想执行一系列请求,并且在它们全部执行后执行另一个操作,您可以使用Futures & Promises Pattern或 defereds。在 jQuery 中,这是通过.promise()
(Futures/Promises) 或.when()
(Deffered) 完成的。
关于全局变量的说明
还值得注意的是,不使用var html = ...
会使您的变量成为全局变量;这通常是不受欢迎的。最好$("body").append(html+"</div>")
在成功处理程序中移动后也声明html
为var html
.