I have a function to do a bubble sort among content of various div
s. for each swap operation, it swaps the divs too, using JQuery Swapsies plugin
. The problem is tht it does the swap once, and after that for other swap operations:
function swap(id1, id2){
$('#' +id1).swap({
target: id2,
opacity: "0.5",
speed: 1000,
callback: function() {
}
});
}
function bubbleSort() {
var ret=[];
$(".num-div").each(function(){ ret.push($(this));});
let swapped;
do {
swapped = false;
for (let i = 1; i < ret.length; ++i) {
if (ret[i - 1].html() > ret[i].html()) {
swap(ret[i-1].attr('id'), ret[i].attr('id'));
[ret[i], ret[i - 1]] = [ret[i - 1], ret[i]];
swapped = true;
}
}
} while (swapped);
return ret;
}
In the first step where i=1
it works and swaps ret[i-1]
with ret[i]
, but after that it does not work.
The swap
plug-in will not process calls when it is busy with an animation. You can see that in the source code of the plug-in:
if (options.target!="" && !swapping) {
The swapping
variable will be true
during an ongoing animation, and that if
will just skip any new animation without notice.
Anyway, you probably want the animations to happen in sequence, not all at the same time. For that purpose I would suggest using promises and the rather new async/await
syntax.
First you would promisify the swap
function, so it returns a promise. Then you add the async
and await
keywords at the appropriate spot, and ... it will work.
One more caution: if your data is numerical, and you want to sort by numeric value, you need to convert strings to numbers before doing the comparison, for instance by applying the unary +
like this: +ret[i].text()
Here is a working demo:
function swap(id1, id2){
return new Promise(resolve =>
$('#' +id1).swap({
target: id2,
opacity: "0.5",
speed: 500,
callback: resolve
})
);
}
async function bubbleSort() {
var ret=[];
$(".num-div").each(function(){
ret.push($(this));
});
let swapped;
do {
swapped = false;
for (let i = 1; i < ret.length; ++i) {
if (ret[i - 1].text() > ret[i].text()) {
await swap(ret[i-1].attr('id'), ret[i].attr('id'));
[ret[i], ret[i - 1]] = [ret[i - 1], ret[i]];
swapped = true;
}
}
} while (swapped);
return ret;
}
bubbleSort().then( ret => {
console.log($.map(ret, x => $(x).text()));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://biostall.com/wp-content/uploads/2010/07/jquery-swapsies.js"></script>
<div id="i1" class="num-div">sort</div>
<div id="i2" class="num-div">these</div>
<div id="i3" class="num-div">words</div>
<div id="i4" class="num-div">in</div>
<div id="i5" class="num-div">alphabetical</div>
<div id="i6" class="num-div">order</div>