Reputation: 6164
I'm trying to do the following:
How can I make sure that only the response to the last request sent will eventually be displayed in its target DIV ?
If I click on the link labelled Data1
, then Data2
, the first call must be aborted because Response1 could arrive after Response2. The problem seems to imply that I must keep track of previous requests for each target, so I can abort them whenever a new request is made.
I've written this piece of code. I'd like to know if you think this is the approach is right.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title></title>
</head>
<body>
<ul>
<li><a href="data1.htm" class="trigger" data-target="d1">Data 1</a></li>
<li><a href="data2.htm" class="trigger" data-target="d1">Data 2</a></li>
<li><a href="data3.htm" class="trigger" data-target="d2">Data 3</a></li>
<li><a href="data4.htm" class="trigger" data-target="d2">Data 4</a></li>
</ul>
<div id="d1"></div>
<div id="d2"></div>
<script type="text/javascript" src="/test/jquery-1.7.1.min.js"></script>
<script type="text/javascript">
$(function(){
var register = {};
$(".trigger").on("click", function() {
var target = $(this).attr("data-target");
var url = $(this).attr("href");
if (register[target] == undefined) register[target] = [];
ajaxCall = $.get(url, function(data) { // Ajax request
$("#" + target).html(data);
});
for (a in register[target]) { // Aborts existing ajax requests for this target
register[target][a].abort();
}
register[target] = []; // Empty register for this target
register[target].push(ajaxCall); // Register current ajax request
return false;
});
});
</script>
</body>
</html>
Upvotes: 0
Views: 1676
Reputation: 154948
Your idea is right in my view. However, you should not use for in
to loop over an array. Also you might want to abort all calls first (just to be sure).
Actually, you're clearing the array each request and only fill it with one ajax call. In this case, it is not necessary to loop over the array, since you know it will only contain one element if the array is not empty. On the other hand, you don't know whether it will contain zero or one element, so a loop is the most concise way to abort a call if it is present.
Also, you can use .data
to get data-
attributes.
Lastly, you could make use of the ||
trick.
var target = $(this).data("target"),
url = $(this).attr("href");
register[target] = register[target] || [];
$.each(register[target], function() {
this.abort();
});
ajaxCall = $.get(url, function(data) { // Ajax request
$("#" + target).html(data);
});
register[target].push(ajaxCall); // Register current ajax request
Upvotes: 2