JSFiddle - React, Tailwind, and code Playground
HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="description" content="">
<meta name="keywords" content="">
<title>Тест</title>
<style>
*{margin:0px;padding:0px;}
html,body{height:100%;}
#middle
{
display:table;
width:100%;
height:100%;
}
#content
{
display:table-cell;
padding:2%;
width:61%;
}
#sidebar
{
display:table-cell;
padding:2%;
width:31%;
background:#ddd;
}
</style>
<script src="обработчик переноса.js"></script>
<script>
DragManager.onDragCancel = function(dragObject) {
dragObject.avatar.rollback();
};
</script>
</head>
<body>
<div id="middle">
<section id="content" class="droppable">
<h1>Content</h1>
<p>сюда перетаскивать элементы</p>
</section>
<aside id="sidebar">
<h2>Sidebar</h2>
<div id="columns">
<div class="draggable" ><header><button>Кнопка с текстом</button></header></div>
<div class="draggable" ><header><input type="radio" checked></header></div>
<div class="draggable" ><header><input type="checkbox" checked></header></div>
<div class="draggable" ><header>
<select>
<option>Пункт 1</option>
<option>Пункт 2</option>
</select></header></div>
</div>
</aside>
</div>
</body>
</html>
JavaScript
var DragManager = new function() {
/**
* составной объект для хранения информации о переносе:
* {
* elem - элемент, на котором была зажата мышь
* avatar - аватар
* downX/downY - координаты, на которых был mousedown
* shiftX/shiftY - относительный сдвиг курсора от угла элемента
* }
*/
var dragObject = {};
var self = this;
function onMouseDown(e) {
if (e.which != 1) return;
var elem = e.target.closest('.draggable');
if (!elem) return;
dragObject.elem = elem;
// запомним, что элемент нажат на текущих координатах pageX/pageY
dragObject.downX = e.pageX;
dragObject.downY = e.pageY;
return false;
}
function onMouseMove(e) {
if (!dragObject.elem) return; // элемент не зажат
if (!dragObject.avatar) { // если перенос не начат...
var moveX = e.pageX - dragObject.downX;
var moveY = e.pageY - dragObject.downY;
// если мышь передвинулась в нажатом состоянии недостаточно далеко
if (Math.abs(moveX) < 3 && Math.abs(moveY) < 3) {
return;
}
// начинаем перенос
dragObject.avatar = createAvatar(e); // создать аватар
if (!dragObject.avatar) { // отмена переноса, нельзя "захватить" за эту часть элемента
dragObject = {};
return;
}
// аватар создан успешно
// создать вспомогательные свойства shiftX/shiftY
var coords = getCoords(dragObject.avatar);
dragObject.shiftX = dragObject.downX - coords.left;
dragObject.shiftY = dragObject.downY - coords.top;
startDrag(e); // отобразить начало переноса
}
// отобразить перенос объекта при каждом движении мыши
dragObject.avatar.style.left = e.pageX - dragObject.shiftX + 'px';
dragObject.avatar.style.top = e.pageY - dragObject.shiftY + 'px';
return false;
}
function onMouseUp(e) {
if (dragObject.avatar) { // если перенос идет
finishDrag(e);
}
// перенос либо не начинался, либо завершился
// в...