I came up with this solution: http://jsfiddle.net/FabienDemangeat/TBYWw/
The idea is to choose the index of the Li element which will move and its destination. If the destination value is inferior to the index of the li element to move, the effect will be reversed.
Some parts are not perfect but it can be a start point. I inspired myself from the snippet provided by "No Surprises"
The main function swapLiElements swaps two li elements and the callback function as parameters allows to do more than one swap easily (see fiddle).
function swapLiElements($northLi, $southLi, isPushingDown, duration, easing, callbackFunction) {
var movement = $northLi.outerHeight();
// Set position of the li elements to relative
$northLi.css('position', 'relative');
$southLi.css('position', 'relative');
// Set the z-index of the moved item to 999 to it appears on top of the other elements
if(isPushingDown)
$northLi.css('z-index', '999');
else
$southLi.css('z-index', '999');
// Move down the first li
$northLi.animate({'top': movement}, {
duration: duration,
queue: false,
easing: easing,
complete: function() {
// Swap the li in the DOM
if(isPushingDown)
$northLi.insertAfter($southLi);
else
$southLi.insertBefore($northLi);
resetLiCssPosition($northLi);
resetLiCssPosition($southLi);
callbackFunction();
}
});
$southLi.animate({'top': -movement}, {
duration: duration,
queue: false,
easing: easing,
});
}