JSFiddle - React, Tailwind, and code Playground
by Upward
HTML
<div class="drop-list">
<div class="line">1</div>
<div class="line">2</div>
<div class="line">3</div>
<div class="line">4</div>
<div class="line">5</div>
</div>
<br><br><br>
<div class="drop-list">
<div class="line">1</div>
<div class="line">2</div>
<div class="line">3</div>
</div>
<br><br><br><br><br><br><br><br><br>
CSS
.line {
background: red;
margin: 2px;
position: relative;
}
.line.active {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
background: yellow;
z-index: 10;
opacity: 0.5;
}
.drop-list {
width: 200px;
}
body.active {
-webkit-user-select: none;
}
JavaScript
var config = {
wrapClass: '.drop-list',
itemClass: '.line'
};
$(config.wrapClass).each(function() {
var $parent = $(this);
var $line;
$(config.itemClass, $parent).on('mousedown.drop', function(e) {
$line = $(this);
var startY = e.clientY;
var diffY;
$line.addClass('active');
$line.on('selectstart', function() {
return false;
});
$('body').on('mousemove.drop', function(e) {
diffY = startY - e.clientY;
$line.css({ top: -diffY });
});
});
$('body').on('mouseup.drop', function(e) {
if (!$line) return;
var length = $(config.itemClass, $parent).length;
var diff = parseInt($line.css('top'));
var height = $line.outerHeight();
var index = $(config.itemClass, $parent).index($line);
var newIndex = Math.round((diff / height));
index = diff > 0 ? index - 1 : index;
newIndex = index + newIndex;
newIndex = newIndex > length - 1 ? length - 1 : newIndex;
if (newIndex >= 0) {
$(config.itemClass, $parent).eq(newIndex).after($line)
} else {
$(config.itemClass, $parent).eq(0).before($line)
}
$('body').off('mousemove.drop').removeClass('active');
$(config.itemClass, $parent).removeClass('active').css({top: 0});
});
});