我的应用程序中有一个Drag& Drop功能,主容器按比例缩小。请查看具有相同功能的jsFiddle。
的 HTML:
<div id="container">
<div class="droppable object0"></div>
<div class="droppable object1"></div>
<div class="draggable object0" id="object0"></div>
</div>
CSS:
#container{
height: 600px;
width: 600px;
border: 3px solid green;
transform: scale(.8);
}
.droppable{
width: 75px;
height: 75px;
border: 3px solid red;
}
#object1{
position: absolute;
left: 100px;
}
.draggable{
width: 200px;
height: 200px;
border: 3px solid blue;
top: 100px;
left: 100px;
position: relative;
}
.location-correct{
background: green;
}
.location-incorrect{
background: red;
}
JS :
var scaleCoefficient = .8;
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');
console.log("a = ",elem)
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) {
onDragCancel(dragObject);
} else {
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;
//avatar.style.width = avatar.offsetWidth * scaleCoefficient;
var id = avatar.id;
$('#' + id).css('transform', 'scale(' + scaleCoefficient + ')');
var topPos = $('#' + id).css('top');
var leftPos = $('#' + id).css('left');
$('#' + id).css('top', '-300px');
$('#' + id).css('left', '-300px');
// инициировать начало переноса
document.body.appendChild(avatar);
avatar.style.zIndex = 9999;
avatar.style.position = 'absolute';
//avatar.style.top = "-200px";
//avatar.style.left = "-300px";
}
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;
function onDragEnd(dragObject, dropElem) {
if (dropElem.classList.contains(dragObject.avatar.classList.item(1))) {
dragObject.elem.style.display = 'none';
dropElem.classList.add("location-correct");
} else {
dragObject.avatar.rollback();
dropElem.classList.add('location-incorrect');
setTimeout(function(){
dropElem.classList.remove('location-incorrect');
}, 1000);
}
};
function onDragCancel(dragObject) {
dragObject.avatar.rollback();
};
};
function getCoords(elem) { // кроме IE8-
var box = elem.getBoundingClientRect();
return {
top: box.top + pageYOffset,
left: box.left + pageXOffset
};
}
每当我拖动一个元素时,元素就会移开光标。我在我的应用程序中解决了这个问题,并且可拖动的对象似乎在光标后面(虽然不能在jsFiddle中重现这个)。但在这种情况下,我无法删除可拖动元素,因为光标无法触摸&#34; droppable元素,因为它们之间有一个可拖动的元素。
有没有人知道是什么原因导致这个问题以及如何修复它?值得指出的是,没有规模,一切正常。感谢