Показать сообщение отдельно
  #3 (permalink)  
Старый 18.05.2019, 08:41
Аватар для Malleys
Профессор
Отправить личное сообщение для Malleys Посмотреть профиль Найти все сообщения от Malleys
 
Регистрация: 20.12.2009
Сообщений: 1,714

Суть такой сортировки: запомнить, какой элемент (источник) начали перетаскивать, затем, когда закончили перетаскивание над каким-то элементом (цель), поместить источник рядом с целью. Всё остальное является визуальным эффектом.

Вот пример...
<table>
	<thead>
		<tr>
			<td><input type="checkbox"></td>
			<td>Title</td>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td><input type="checkbox"></td>
			<td>He’s Back: Steve Jobs Adds Rock ana Roll Flair</td>
		</tr>
		<tr>
			<td><input type="checkbox"></td>
			<td>TDGU Gadget Wishlist</td>
		</tr>
		<tr>
			<td><input type="checkbox"></td>
			<td>Right Track</td>
		</tr>
		<tr>
			<td><input type="checkbox"></td>
			<td>3D TV: welcome to the third dimension</td>
		</tr>
		<tr>
			<td><input type="checkbox"></td>
			<td>But who has any right to find fault with a man</td>
		</tr>
	</tbody>
	<tfoot>
		<tr>
			<td><input type="checkbox"></td>
			<td>Title</td>
		</tr></tfoot>
</table>

<style>
	table {
		border-collapse: collapse;
		border-spacing: 0;
		box-shadow: 0 0 1px rgba(0, 0, 0, 0.5);
	}
	
	thead { box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.1); }
	tfoot { box-shadow: inset 0  1px 0 rgba(0, 0, 0, 0.1); }
	tbody > tr:nth-child(even) { background-color: white;   }
	tbody > tr:nth-child(odd)  { background-color: #f5f5f5; }
	
	tbody > tr {
		-webkit-user-drag: element;
		-webkit-user-select: none;
		user-select: none;
		cursor: move;
	}
	
	tbody > tr.over-effect {
		background-color: #E3F2FD;
		filter: drop-shadow(0 -2px 0 #2196f3);
		z-index: 1;
		position: relative;
	}
	
	tbody > tr.source-effect ~ tr.over-effect {
		filter: drop-shadow(0 2px 0 #2196f3);
	}

	tbody > tr.source-effect {
		background-color: #2196f3;
		color: white;
		filter: none;
	}
	
	td { padding: .5em; margin: 1px; }
</style>


<script>
	
var source, over;
	
addEventListener("dragstart", event => {
	event.dataTransfer.effectAllowed = "move";
	event.dataTransfer.setData("text/plain", "");
	source = event.target.closest("tbody > tr");
	if(source) setTimeout(() => source.classList.add("source-effect"));
});
	
//addEventListener("dragenter", event => {});
	
addEventListener("dragover", event => {
	event.preventDefault();
	event.dataTransfer.dropEffect = "move";
	if(over) over.classList.remove("over-effect");
	over = event.target.closest("tbody > tr");
	if(over) over.classList.add("over-effect");
});
	
addEventListener("dragleave", event => {
	if(over) over.classList.remove("over-effect");
});
	
addEventListener("dragend", event => {
	if(over) over.classList.remove("over-effect");
	if(source) source.classList.remove("source-effect");
});
	
addEventListener("drop", event => {
	var destination = event.target.closest("tbody > tr");
	if(!destination || destination == source) return;
	
	var isDestinationAmongNextSiblings = false, node = source;
	
	while(node = node.nextElementSibling) {
		if(node === destination) {
			isDestinationAmongNextSiblings = true;
			break;
		}
	}
	
	destination.parentNode.insertBefore(source, isDestinationAmongNextSiblings ? destination.nextElementSibling : destination);
});
	
for(const row of document.querySelectorAll("tbody > tr")) {
	row.draggable = true;
}
	
Text.prototype.closest = function(selector) {
	return this.parentNode.closest(selector);
}
	
</script>
Ответить с цитированием