封装一个简单的拖拽+变形的div的模块
在编写拖拽与变形之前,我们需要知道DOM与元素大小相关的属性
需要的参数:被拖动的元素css选择器elemSelector,容器元素选择器wrapSelector
拖拽+边界指针提示部分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
| function dragElement (elemSelector, wrapSelector) { let elemDom = document.querySelector(elemSelector) let wrapDom = document.querySelector(wrapSelector)
let { offsetHeight, offsetWidth } = elemDom let mouseDownOffsetX, mouseDownOffsetY, mouseMoveClientX, mouseMoveClientY, elemLeft, elemTop wrapDom.style.position = 'relative' elemDom.style.position = 'absolute' elemDom.addEventListener('mousemove', elemMouseMove)
function onElemMousedown (e) { mouseMoveClientX = e.clientX mouseMoveClientY = e.clientY wrapDom.addEventListener('mousemove', mouseMoveOnWrap) wrapDom.addEventListener('mouseup', removeListener) wrapDom.addEventListener('mouseleave', removeListener) }
function mouseMoveOnWrap (e) { clientX = e.clientX clientY = e.clientY elemLeft = mouseMoveClientX - mouseDownOffsetX elemTop = mouseMoveClientY - mouseDownOffsetY elemDom.style.left = elemLeft + 'px' elemDom.style.top = elemTop + 'px'
}
function elemMouseMove (e) { const { offsetX, offsetY } = e offsetHeight = e.target.offsetHeight offsetWidth = e.target.offsetWidth if (offsetX > 6 && offsetX < offsetWidth - 6 && offsetY > 6 && offsetY < offsetHeight - 6) { e.target.style.cursor = 'move' elemDom.addEventListener('mousedown', onElemMousedown) return null } else if (offsetY > -5 && offsetY < 5) { if (offsetX > -5 && offsetX < 5) { e.target.style.cursor = 'nw-resize' } else if (offsetX > offsetWidth - 5 && offsetX < offsetWidth + 5) { e.target.style.cursor = 'ne-resize' } else { e.target.style.cursor = 'n-resize' } } else if (offsetY > offsetHeight - 5 && offsetY < offsetHeight + 5) { if (offsetX > -5 && offsetX < 5) { e.target.style.cursor = 'sw-resize' } else if (offsetX > offsetWidth - 5 && offsetX < offsetWidth + 5) { e.target.style.cursor = 'se-resize' } else { e.target.style.cursor = 'n-resize' } } else if (offsetX > -5 && offsetX < 5 || offsetX > offsetWidth - 5 && offsetX < offsetWidth + 5) { e.target.style.cursor = 'e-resize' } else { e.target.style.cursor = 'default' } elemDom.removeEventListener('mousedown', onElemMousedown) }
function removeListener (e) { e.target.style.cursor = 'default' wrapDom.removeEventListener('mousemove', mouseMoveOnWrap) wrapDom.removeEventListener('mouseup', arguments.callee) wrapDom.removeEventListener('mouseleave', arguments.callee) } }
|
边缘拖拽变形部分
所需参数,被拖动的元素选择器elemSelector,拖动元素的最小宽度和高度
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| function resizeRect (elemSelector, minWidth, minHeight) {
let clientClickDownX, clientClickDownY, currentClientX, currentClientY, rectMouseOffsetX, rectMouseOffsetY let elemDom = document.querySelector(elemSelector) let elemHeight = elemDom.offsetHeight let elemWidth = elemDom.offsetWidth let elemTop = elemDom.offsetTop let elemLeft = elemDom.offsetLeft elemDom.style.minHeight = minHeight + 'px' elemDom.style.minWidth = minWidth + 'px' elemDom.addEventListener('mousedown', function (e) { clientClickDownX = e.clientX clientClickDownY = e.clientY rectMouseOffsetX = e.offsetX rectMouseOffsetY = e.offsetY if (rectMouseOffsetY > 0 && rectMouseOffsetY < 5) { document.addEventListener('mousemove', rectTopResize) } if (rectMouseOffsetY < elemHeight + 5 && rectMouseOffsetY > elemHeight - 5) { document.addEventListener('mousemove', rectBottomResize) } if (rectMouseOffsetX > -5 && rectMouseOffsetX < 5) { document.addEventListener('mousemove', rectLeftResize) } if (rectMouseOffsetX < elemWidth + 5 && rectMouseOffsetX > elemWidth - 5) { document.addEventListener('mousemove', rectRightResize) } }) document.addEventListener('mouseup', function () { elemTop = elemDom.offsetTop elemLeft = elemDom.offsetLeft elemHeight = elemDom.offsetHeight elemWidth = elemDom.offsetWidth document.removeEventListener('mousemove', rectTopResize) document.removeEventListener('mousemove', rectBottomResize) document.removeEventListener('mousemove', rectLeftResize) document.removeEventListener('mousemove', rectRightResize)
}) function rectTopResize (e) { currentClientY = e.clientY elemDom.style.height = elemHeight + (clientClickDownY - currentClientY) + 'px' if (elemDom.offsetHeight === minHeight) { elemDom.style.top = elemDom.offsetTop + 'px' } else { elemDom.style.top = elemTop - (clientClickDownY - currentClientY) + 'px' }
} function rectBottomResize (e) { currentClientY = e.clientY elemDom.style.height = elemHeight + (currentClientY - clientClickDownY) + 'px' }
function rectLeftResize (e) { currentClientX = e.clientX elemDom.style.width = elemWidth + (clientClickDownX - currentClientX) + 'px' if (elemDom.offsetWidth === minWidth) { elemDom.style.left = elemDom.offsetLeft + 'px' } else { elemDom.style.left = elemLeft - (clientClickDownX - currentClientX) + 'px' } }
function rectRightResize (e) { currentClientX = e.clientX elemDom.style.width = elemWidth + (currentClientX - clientClickDownX) + 'px' } }
|
暴露模块
使用匿名函数自调用(IIFE),将函数挂载到windows中,成为全局方法,参数minWidth和minHeight默认为5px
1 2 3 4 5 6
| (function (window) { window.dragResize = function (elemSelector, wrapSelector, minWidth = 5, minHeight = 5) { dragElement(elemSelector, wrapSelector) resizeRect(elemSelector, minWidth, minHeight) } })(window)
|
最终的效果,请访问drag-resize