JavaScript原生实现HTML元素8方位拉伸拖拽
程序员文章站
2022-07-10 21:49:30
JavaScript原生实现HTML元素8方位拉伸拖拽实现思路代码实现实现思路拖拽元素(窗口)的实现很简单,在此不过多阐述,主要是选中元素,计算相对位置,然后将事件聚焦到待拖动的元素里面,计算移动的距离,应用到元素的CSS样式上,最后释放事件就可以了。8方位的拉伸,网上现在先行的比较流行的代码是在一个DIV里面添加8个DIV以确定方位角,(但是这种方法真的是low爆了)完全不符合现行的模块化开发思路。(我总不能为了做个拉伸,还得在里面添加8个无用的DIV吧)所以,最好的方式,就是鼠标到元素(窗口)的指...
实现思路
拖拽元素(窗口)的实现很简单,在此不过多阐述,主要是选中元素,计算相对位置,然后将事件聚焦到待拖动的元素里面,计算移动的距离,应用到元素的CSS样式上,最后释放事件就可以了。
8方位的拉伸,网上现在先行的比较流行的代码是在一个DIV里面添加8个DIV以确定方位角,(但是这种方法真的是low爆了)完全不符合现行的模块化开发思路。(我总不能为了做个拉伸,还得在里面添加8个无用的DIV吧)所以,最好的方式,就是鼠标到元素(窗口)的指定位置,就能变换光标样式,(就和你在window里面拉动窗口一样)这样就必然会使用到mousemove事件,所以只要能确定元素的X/Y向偏移和元素自身的长宽,这个问题就很好解决了。
对于拉伸而言,方位检测一旦完成,拉伸就很好做了,和拖拽的思路基本一致,拖拽是改变元素的top/left值,而拉伸改变的是height/width/top/left的值罢了。
代码实现
<html>
<head>
</head>
<body>
<div id="main" style="width: 200px; height: 200px; background: #cccccc;"></div>
<script>
const el = document.querySelector('#main')
el.style.position = 'absolute'
el.style.top = '100px'
el.style.left = '100px'
el.style.zIndex = "99"
const accuracy = 10
const minWidth = 100
const minHeight = 100
el.onmousemove = (event) => {
const x = event.clientX
const y = event.clientY
const topYUpperLimit = el.offsetTop + accuracy, topYLowerLimit = el.offsetTop
const bottomYUpperLimit = el.offsetTop + el.clientHeight, bottomYLowerLimit = el.offsetTop + el.clientHeight - accuracy
const leftXUpperLimit = el.offsetLeft + accuracy, leftXLowerLimit = el.offsetLeft
const rightXUpperLimit = el.offsetLeft + el.clientWidth, rightXLowerLimit = el.offsetLeft + el.clientWidth - accuracy
const CENTER = 0, LEFTTOP = 1, TOP = 2, RIGHTTOP = 3, RIGHT = 4, RIGHTBOTTOM = 5, BOTTOM = 6, LEFTBOTTOM = 7, LEFT = 8
const checkWindowSize = (el) => {
if (parseInt(el.style.width) < minWidth) {
el.style.width = minWidth + 'px'
}
if (parseInt(el.style.height) < minHeight) {
el.style.height = minHeight + 'px'
}
}
const mouseDownHandler = (el, location) => {
el.onmousedown = (event) => {
const initX = event.clientX, initY = event.clientY
const clientX = el.clientWidth, clientY = el.clientHeight
const offsetX = el.offsetLeft, offsetY = el.offsetTop
const relativeX = event.clientX - el.offsetLeft, relativeY = event.clientY - el.offsetTop
const windowInnerWidth = window.innerWidth, windowInnerHeight = window.innerHeight
if (typeof el.setCapture !== 'undefined') {
el.setCapture()
}
document.onmousemove = (event) => {
if (location == LEFTTOP) {
const moveX = event.clientX - initX
const moveY = event.clientY - initY
el.style.left = offsetX + moveX + 'px'
el.style.top = offsetY + moveY + 'px'
el.style.width = clientX - moveX + 'px'
el.style.height = clientY - moveY + 'px'
} else if (location == TOP) {
const moveY = event.clientY - initY
el.style.top = offsetY + moveY + 'px'
el.style.height = clientY - moveY + 'px'
} else if (location == RIGHTTOP) {
const moveX = event.clientX - initX
const moveY = event.clientY - initY
el.style.top = offsetY + moveY + 'px'
el.style.width = clientX + moveX + 'px'
el.style.height = clientY - moveY + 'px'
} else if (location == RIGHT) {
const moveX = event.clientX - initX
el.style.width = clientX + moveX + 'px'
} else if (location == RIGHTBOTTOM) {
const moveX = event.clientX - initX
const moveY = event.clientY - initY
el.style.width = clientX + moveX + 'px'
el.style.height = clientY + moveY + 'px'
} else if (location == BOTTOM) {
const moveY = event.clientY - initY
el.style.height = clientY + moveY + 'px'
} else if (location == LEFTBOTTOM) {
const moveX = event.clientX - initX
const moveY = event.clientY - initY
el.style.left = offsetX + moveX + 'px'
el.style.width = clientX - moveX + 'px'
el.style.height = clientY + moveY + 'px'
} else if (location == LEFT) {
const moveX = event.clientX - initX
const moveY = event.clientY - initY
el.style.left = offsetX + moveX + 'px'
el.style.width = clientX - moveX + 'px'
} else if (location == CENTER) {
let moveX = event.clientX - relativeX
let moveY = event.clientY - relativeY
if (moveX < 0) {
moveX = 0
}
if (moveY < 0) {
moveY = 0
}
if (moveX > windowInnerWidth - el.clientWidth) {
moveX = windowInnerWidth - el.clientWidth
}
if (moveY > windowInnerHeight - el.clientHeight) {
moveY = windowInnerHeight - el.clientHeight
}
el.style.left = moveX + 'px'
el.style.top = moveY + 'px'
}
checkWindowSize(el)
}
document.onmouseup = (event) => {
el.onmousedown = null
document.onmousemove = null
document.onmouseup = null
if (typeof el.setCapture !== 'undefined') {
el.releaseCapture()
}
}
}
}
if (leftXLowerLimit < x && x < leftXUpperLimit && topYLowerLimit < y && y < topYUpperLimit) {
// console.log('左上角')
el.style.cursor = 'nw-resize'
mouseDownHandler(el, LEFTTOP)
} else if (rightXLowerLimit < x && x < rightXUpperLimit && topYLowerLimit < y && y < topYUpperLimit) {
// console.log('右上角')
el.style.cursor = 'ne-resize'
mouseDownHandler(el, RIGHTTOP)
} else if (rightXLowerLimit < x && x < rightXUpperLimit && bottomYLowerLimit < y && y < bottomYUpperLimit) {
// console.log('右下角')
el.style.cursor = 'se-resize'
mouseDownHandler(el, RIGHTBOTTOM)
} else if (leftXLowerLimit < x && x < leftXUpperLimit && bottomYLowerLimit < y && y < bottomYUpperLimit) {
// console.log('左下角')
el.style.cursor = 'sw-resize'
mouseDownHandler(el, LEFTBOTTOM)
} else if (topYLowerLimit < y && y < topYUpperLimit){
// console.log('上边缘')
el.style.cursor = 'n-resize'
mouseDownHandler(el, TOP)
} else if (bottomYLowerLimit < y && y < bottomYUpperLimit) {
// console.log('下边缘')
el.style.cursor = 's-resize'
mouseDownHandler(el, BOTTOM)
} else if (leftXLowerLimit < x && x <leftXUpperLimit) {
// console.log('左边缘')
el.style.cursor = 'w-resize'
mouseDownHandler(el, LEFT)
} else if (rightXLowerLimit < x && x < rightXUpperLimit) {
// console.log('右边缘')
el.style.cursor = 'e-resize'
mouseDownHandler(el, RIGHT)
} else {
el.style.cursor = 'pointer'
mouseDownHandler(el, CENTER)
}
}
</script>
</body>
</html>
本文地址:https://blog.csdn.net/codebooks/article/details/107310747