export function drag ( { mouseDownEvent, element, once = false, mouseDownCallback = () => {}, mouseMoveCallback = () => {}, mouseUpCallback = () => {} }) { if (!mouseDownEvent && !element) { console.error('Must provide mouseDownEvent or element') } if (mouseDownEvent && !(mouseDownEvent instanceof MouseEvent)) { console.error('mouseDownEvent must be instance of MouseEvent', mouseDownEvent) return } if (!mouseDownEvent && element) { const fn = event => { drag({ mouseDownEvent: event, mouseDownCallback, mouseMoveCallback, mouseUpCallback: event => { if (once) { element.removeEventListener('mousedown', fn) } mouseDownCallback(event) } }) } element.addEventListener('mousedown', fn) return } let moveInfo = {} function mouseDown () { const currentTarget = mouseDownEvent.currentTarget if (!currentTarget) { console.error('No currentTarget property', mouseDownEvent) } if (!currentTarget.getBoundingClientRect) { console.error('Element is not support getBoundingClientRect function', currentTarget) } // x、y、width、height may not exist const {left, right, top, bottom} = currentTarget.getBoundingClientRect() const width = right - left const height = bottom - top const moveElm = currentTarget.cloneNode(true) moveElm.style.position = 'fixed' moveElm.style.zIndex = 999 moveElm.style.left = left + 'px' moveElm.style.top = top + 'px' moveElm.style.width = width + 'px' moveElm.style.height = height + 'px' if (moveElm.style.userSelect) { moveElm.style.userSelect = 'none' } if (moveElm.style.msUserSelect) { moveElm.style.msUserSelect = 'none' } if (moveElm.style.webkitUserSelect) { moveElm.style.webkitUserSelect = 'none' } if (moveElm.style.mozUserSelect) { moveElm.style.mozUserSelect = 'none' } const overlay = document.createElement('div') overlay.style.text = [ 'position: fixed', 'left: 0', 'right: 0', 'top: 0', 'bottom: 0', 'z-index: 998' ].join(';') currentTarget.parentElement.insertBefore(moveElm, currentTarget) document.body.appendChild(overlay) moveInfo = { left, top, width, height, startX: mouseDownEvent.x, startY: mouseDownEvent.y, moveElm, overlay } document.addEventListener('mousemove', mouseMove) document.addEventListener('mouseup', mouseUp) mouseDownCallback(mouseDownEvent) } function mouseMove (event) { const currentX = event.x const currentY = event.y moveInfo.moveElm.style.left = moveInfo.left + currentX - moveInfo.startX + 'px' moveInfo.moveElm.style.top = moveInfo.top + currentY - moveInfo.startY + 'px' mouseMoveCallback(event) } function mouseUp (event) { document.removeEventListener('mousemove', mouseMove) document.removeEventListener('mouseup', mouseUp) moveInfo.moveElm.parentElement.removeChild(moveInfo.moveElm) document.body.removeChild(moveInfo.overlay) mouseUpCallback(event) } mouseDown() }