Не работает element.style если у element есть какое-либо значение display
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);
}
// перенос либо не начинался, либо завершился
// в любом случае очистим "состояние переноса" dragObject
dragObject = {};
}
function finishDrag(e) {
var dropElem = findDroppable(e);
if (!dropElem) {
self.onDragCancel(dragObject);
} else {
self.onDragEnd(dragObject, dropElem);
}
}
function createAvatar(e) {
// запомнить старые свойства, чтобы вернуться к ним при отмене переноса
var avatar = dragObject.elem;
var old = {
parent: avatar.parentNode,
nextSibling: avatar.nextSibling,
position: avatar.position || '',
left: avatar.left || '',
top: avatar.top || '',
zIndex: avatar.zIndex || ''
};
// функция для отмены переноса
avatar.rollback = function() {
old.parent.insertBefore(avatar, old.nextSibling);
avatar.style.position = old.position;
avatar.style.left = old.left;
avatar.style.top = old.top;
avatar.style.zIndex = old.zIndex
};
return avatar;
}
function startDrag(e) {
var avatar = dragObject.avatar;
// инициировать начало переноса
document.body.appendChild(avatar);
avatar.style.zIndex = 9999;
avatar.style.position = 'absolute';
}
function findDroppable(event) {
// спрячем переносимый элемент
dragObject.avatar.hidden = true;
// получить самый вложенный элемент под курсором мыши
var elem = document.elementFromPoint(event.clientX, event.clientY);
// показать переносимый элемент обратно
dragObject.avatar.hidden = false;
if (elem == null) {
// такое возможно, если курсор мыши "вылетел" за границу окна
return null;
}
return elem.closest('.droppable');
}
document.onmousemove = onMouseMove;
document.onmouseup = onMouseUp;
document.onmousedown = onMouseDown;
this.onDragEnd = function(dragObject, dropElem) {};
this.onDragCancel = function(dragObject) {};
};
function getCoords(elem) { // кроме IE8-
var box = elem.getBoundingClientRect();
return {
top: box.top + pageYOffset,
left: box.left + pageXOffset
};
}
.computer {
width: 93px;
height: 98px;
background: url(https://js.cx/clipart/computer.gif) no-repeat;
padding: 5px;
font-style: italic;
}
.computer-smile {
background: url(https://js.cx/clipart/computer-smile.gif) no-repeat;
}
.draggable {
cursor: pointer;
/*Если добавить display, то элементы перестанут исчезать при бросании в компьютер*/
/*display: inline-block*/
}
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<script src="https://cdn.polyfill.io/v1/polyfill.js?features=Element.prototype.closest"></script>
<script src="DragManager.js"></script>
<link rel="stylesheet" href="dragDemo.css">
<script>
DragManager.onDragCancel = function(dragObject) {
dragObject.avatar.rollback();
};
DragManager.onDragEnd = function(dragObject, dropElem) {
dragObject.elem.style.display = 'none';
dropElem.classList.add('computer-smile');
setTimeout(function() {
dropElem.classList.remove('computer-smile');
}, 200);
};
</script>
</head>
<body>
<div style="height:64px">
<img src="https://js.cx/browsers/chrome.svg" class="draggable">
<img src="https://js.cx/browsers/firefox.svg" class="draggable">
<img src="https://js.cx/browsers/ie.svg" class="draggable">
<img src="https://js.cx/browsers/opera.svg" class="draggable">
<img src="https://js.cx/browsers/safari.svg" class="draggable">
</div>
<p>Браузер переносить сюда:</p>
<div class="computer droppable">
</div>
</body>
</html>
Делаю Drag and Drop на сайте. Столкнулся с проблемой. Брал код из этой статьи: https://learn.javascript.ru/drag-and-drop-objects (в конце есть полный код)
Ради интереса полностью скопировал пример и оказалось, что если у draggable элемента есть какой-либо display в css, то эта строчка (она находится в head файла html)...
dragObject.elem.style.display = 'none';
она просто не работает. Причём даже если display в строчке поменять на любой другой стиль, то она всё равно не будет работать, если в css уже есть любой display. Почему так происходит не могу разобраться уже второй день. Помогите пожалуйста объяснить этот феномен...