103 lines
3.3 KiB
HTML
103 lines
3.3 KiB
HTML
|
<!DOCTYPE html>
|
||
|
<html>
|
||
|
<head>
|
||
|
<meta charset="utf-8">
|
||
|
<title>Sortable Lists</title>
|
||
|
<style>
|
||
|
#sortable > li {
|
||
|
cursor: move;
|
||
|
}
|
||
|
.hover {
|
||
|
color: orange;
|
||
|
}
|
||
|
</style>
|
||
|
</head>
|
||
|
<body>
|
||
|
<h1>Sortable Lists</h1>
|
||
|
|
||
|
<ul id="sortable">
|
||
|
<li>foo</li>
|
||
|
<li>bar</li>
|
||
|
<li>baz</li>
|
||
|
<li>quux</li>
|
||
|
</ul>
|
||
|
|
||
|
<script>
|
||
|
makeSortable(document.getElementById('sortable'));
|
||
|
|
||
|
function makeSortable(sortable) {
|
||
|
var tempItem = document.createElement('li');
|
||
|
var dataType = 'list-item';
|
||
|
var currentIndex = -1;
|
||
|
|
||
|
for (var i = 0, n = sortable.children.length; i < n; i++) {
|
||
|
var item = sortable.children.item(i);
|
||
|
|
||
|
item.draggable = 'true';
|
||
|
|
||
|
item.ondragstart = function(e) {
|
||
|
currentIndex = getChildIndex(e.target);
|
||
|
e.dataTransfer.setData(dataType, currentIndex);
|
||
|
e.dataTransfer.effectAllowed = 'move';
|
||
|
};
|
||
|
|
||
|
item.ondragover = function(e) {
|
||
|
var types = e.dataTransfer.types;
|
||
|
|
||
|
if (types.contains) { // For FF.
|
||
|
var canDrop = types.contains(dataType);
|
||
|
} else if (types.indexOf) { // For Chrome and Safari.
|
||
|
canDrop = types.indexOf(dataType) !== -1;
|
||
|
}
|
||
|
|
||
|
if (canDrop) {
|
||
|
if (getChildIndex(e.target) !== currentIndex) {
|
||
|
e.dataTransfer.dropEffect = 'move';
|
||
|
e.preventDefault(); // Allows the drop.
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
item.ondrop = function(e) {
|
||
|
var startIndex = +e.dataTransfer.getData(dataType);
|
||
|
var startItem = sortable.children.item(startIndex);
|
||
|
var endItem = e.target;
|
||
|
sortable.replaceChild(tempItem, endItem);
|
||
|
sortable.replaceChild(endItem, startItem);
|
||
|
sortable.replaceChild(startItem, tempItem);
|
||
|
endItem.classList.remove('hover');
|
||
|
e.preventDefault(); // For FF.
|
||
|
return false; // For IE.
|
||
|
};
|
||
|
|
||
|
item.ondragenter = function(e) {
|
||
|
if (e.target.nodeType === 1) { // FF raises event on text nodes?
|
||
|
if (getChildIndex(e.target) !== currentIndex) {
|
||
|
e.target.classList.add('hover');
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
item.ondragleave = function(e) {
|
||
|
if (e.target.nodeType === 1) { // FF raises event on text nodes?
|
||
|
if (getChildIndex(e.target) !== currentIndex) {
|
||
|
e.target.classList.remove('hover');
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
|
||
|
function getChildIndex(node) {
|
||
|
var index = 0;
|
||
|
while (node.previousSibling) {
|
||
|
node = node.previousSibling;
|
||
|
if (node.nodeType === 1) {
|
||
|
index++;
|
||
|
}
|
||
|
}
|
||
|
return index;
|
||
|
}
|
||
|
}
|
||
|
</script>
|
||
|
</body>
|
||
|
</html>
|