我有一系列要异步加载的内容网址,例如
var toLoad = ['snippet1.html', 'snippet2.html', ... ];
我正在尝试使用AJAX加载每个代码段并将其附加到父<div>
,从而维护数组中内容的顺序。由于我的其余代码的设置方式(以及出于性能原因),我不希望以同步方式加载,使用async:false
或链接{{ 1}}调用,如this similar question的答案所示。相反,我想在AJAX回调函数中放置逻辑,以便根据索引正确放置加载的代码段。
以下代码有效:
.ajax()
......但我不喜欢它。特别是,我不喜欢使用var $parent = $('#mydiv');
toLoad.forEach(function(url, i) {
// load snippet
$.get(url, function(snippet) {
// attach order to DOM element
snippet = $(snippet).data('order', i);
// find the sibling with the next lowest order number
var $prev = $parent
.children()
.filter(function() {
return $(this).data('order') < i
})
.last();
if ($prev[0]) snippet.insertAfter($prev);
else $parent.prepend(snippet);
});
});
将订单附加到DOM元素;这看起来很难看,如果我能帮助它,我宁愿不把它粘在DOM上。
有没有更好的方法来实现将内容异步加载到具有预定义顺序的div中的目标?
答案 0 :(得分:3)
有一个简单的递归,等到下一个开始之前完成一个递归:
var toLoad = ['snippet1.html', 'snippet2.html', ....];
var $parent = $('#mydiv');
var i = 0;
getSnippet(toLoad[i]);
function getSnippet(url) {
$.get(url, function(snippet) {
$parent.append(snippet);
if (i<toLoad.length) getSnippet(toLoad[i++]);
});
}
然后立即执行所有操作,只需将它们粘贴在一个数组中,依次运行done()
函数以确保元素按顺序插入:
var toLoad = ['snippet1.html', 'snippet2.html', 'snippet3.html'];
var $parent = $('#mydiv');
var gets = [];
toLoad.forEach(function(url, i) {
var XHR = $.get(url);
gets.push(XHR);
});
gets[0].done(function(snippet) {
$parent.append(snippet);
gets[1].done(function(snippet) {
$parent.append(snippet);
gets[2].done(function(snippet) {
$parent.append(snippet);
});
});
});
如果做了很多ajax调用,可能会在某种循环中完成。
$.when($.get(toLoad[0]),
$.get(toLoad[1])
$.get(toLoad[2])
).done(function(value1, value2, value3) {
// value1 etc. are arguments resolved for the ajax requests, respectively
// arguments are [ "success", statusText, jqXHR ]
$parent.append(value1[2]+value2[2]+value3[2]);
}
});
答案 1 :(得分:2)
如果你的主要抱怨是使用.data(),你可以维护自己的数组,它将dom节点元素与值相关联。
var map = [
{order: 5, nodeReference: ...},
{order: 9, nodeReference: ...},
{order: 1, nodeReference: ...}
];
function data(node) {
// loop through map, comparing to nodeReference to get the order
}
//然后 ...
.filter(function() {
return data(this) < i
})
您的代码大部分保持不变,除非您在向dom附加内容时需要添加到地图中。
我会尽力继续逐渐加载dom,就像你现在一样。我不会等到所有东西都被加载,或者甚至按顺序添加它们。让订单最终像你现在一样自行完成。这就是Web浏览器在网页中加载图像的方式,而且有很深的理由。