javascript中的错误行为与缩放元素拖放

时间:2017-04-01 11:33:09

标签: javascript drag-and-drop scale

我的应用程序中有一个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元素,因为它们之间有一个可拖动的元素。
有没有人知道是什么原因导致这个问题以及如何修复它?值得指出的是,没有规模,一切正常。感谢

0 个答案:

没有答案