I have a question and I’m very surprised that I’ve never seen any script implementing such a technique, but I can’t solve it on my own, so I need a clue. To see what I want, please check out this basic page:
<!DOCTYPE html>
<html lang="en">
<head>
<style>
#loading{
display:none;
position: fixed;
width:500px;
height:200px;
top: 50%;
left: 50%;
margin-top: -100px;
margin-left: -250px;
z-index: 1;
border:black thin solid;
background-color: gold;}
</style>
<script src="path/to/jquery.min.js"></script>
<script>
$(document).ready(function () {
$('.click').click(function () {
$("#content").empty();
var src = $(this).attr('data-source').split(';');
var l = src.length;
$("#loading").ajaxStart(function(){
$(this).html("Loading, please wait...").show();
}).ajaxStop(function(){
$(this).hide();
});
if (src.length >= 1 && src.length <= 5) {
$.get(src[0].substring(src[0].lastIndexOf('@') + 1), {}, function (data) {
var $response = $('<div />').html(data);
$('#content').append($response.find(src[0].substring(0, src[0].lastIndexOf('@'))));
}, 'html').complete(function () {
$('#loading').html('Loaded: 1. Total: ' + l);
if (src.length >= 2) {
$.get(src[1].substring(src[1].lastIndexOf('@') + 1), {}, function (data) {
var $response = $('<div />').html(data);
$('#content').append($response.find(src[1].substring(0, src[1].lastIndexOf('@'))));
}, 'html').complete(function () {
$('#loading').html('Loaded: 2. Total: ' + l);
if (src.length >= 3) {
$.get(src[2].substring(src[2].lastIndexOf('@') + 1), {}, function (data) {
var $response = $('<div />').html(data);
$('#content').append($response.find(src[2].substring(0, src[2].lastIndexOf('@'))));
}, 'html').complete(function () {
$('#loading').html('Loaded: 3. Total: ' + l);
if (src.length >= 4) {
$.get(src[3].substring(src[3].lastIndexOf('@') + 1), {}, function (data) {
var $response = $('<div />').html(data);
$('#content').append($response.find(src[3].substring(0, src[3].lastIndexOf('@'))));
}, 'html').complete(function () {
$('#loading').html('Loaded: 4. Total: ' + l);
if (src.length >= 5) {
$.get(src[4].substring(src[4].lastIndexOf('@') + 1), {}, function (data) {
var $response = $('<div />').html(data);
$('#content').append($response.find(src[4].substring(0, src[4].lastIndexOf('@'))));
}, 'html').complete(function () {
$('#loading').html('Loaded: 5. Total: ' + l);
});
}
});
}
});
}
});
}
});
}
});
});
</script>
</head>
<body>
<span data-source="#part1, #part3, #part4@page1.html;#part2@page2.html;#part5@page1.html" class="click">Click me</span>
<div id="content">
</div>
<div id="loading">Loading, please wait...</div>
</body>
</html>
That is, the elements are loading strictly in the order that I specified in my “data-source” attribute.
This script seems to work as I expect, but the problem is that I don’t want to “manually” write a separate function for every possible length!!! I want a script that will do this job automatically! I tried this:
jQuery.each(src, function (i) {
$.get(src[i].substring(src[i].lastIndexOf('@') + 1), {}, function (data) {
var $response = $('<div />').html(data);
var $ids = $response.find(src[i].substring(0, src[i].lastIndexOf('@')));
$('#content').append($ids);
}, 'html').complete(function () {
$('#loading').html('Loaded: ' + (i + 1) + '. Total:' + l);
});
});
But in this case, due to the very nature of AJAX and the fact that jQuery.each is not equivalent to an infinite .complete(function () {… .complete(function () {… .complete(function () {… , the elements will not append in the same order that I specified, especially if they come from the same page. And if I write my data-source attribute as “page 1.html #part1, #part2” and use something like this:
jQuery.each(src, function (i) {
$('<div />').attr('class', 'container').appendTo($('#content')).load(src[i], function() {
$('#loading').html('Loaded: ' + (i + 1) + '. Total:' + l);
});
});
The elements seem to append in a right order, and they do it the way I can’t understand: one just shifts down another, taking its place between the two already existing elements! But I can’t imagine where that HTML in my loading message comes from, it may just show that the pages are loading from last to first. I also tried to make use of ajaxComplete event and manipulate with the “data” attribute after my first Ajax call, but got no results.
So, is ajaxComplete equal to .complete(function () {… .complete(function () {… .complete(function () {… ? If it is, how can I tell to the script: “Start with the first element of this array, forget about the others. When you’re done, switch to the next… and so on, till the end”
I would suggest following solution with recursion: