前言
学习编程可以追溯到高中时代,回首望去20多年,有遗憾,因为没能真正从事这方面职业,但是兴趣使然一直没有放弃,大大小小项目也开发过,独立的合作的都有。突发奇想也许我也能写写东西,是分享,也是学习,更是想交朋友。今天分享一个窗口拖拽功能。希望大家喜欢!
正题
先上图
需要8个方向拖拽与鼠标按住移动,这个功能应该是比较常见的,当然网上的教程很多,不过我还是自己写了一个适合自己的,当然,参考是必不可少的!!
按住拖拽
先上代码
export const PressDrop = (moveTarget: MaybeRef<HTMLElement | null>, target: MaybeRef<HTMLElement | null>) => {
const onMouseDown = (e: MouseEvent) => {
e.preventDefault()
const move = unrefElement(moveTarget)
const el = unrefElement(target)
if (!el || !move)
return
const distanceX = e.clientX - el.offsetLeft
const distanceY = e.clientY - el.offsetTop
document.onmousemove = (e: MouseEvent) => {
e.preventDefault()
el.style.left = e.clientX - distanceX + 'px'
el.style.top = e.clientY - distanceY + 'px'
}
document.onmouseup = (e: MouseEvent) => {
e.preventDefault()
document.onmousemove = null
document.onmouseup = null
}
}
if (moveTarget && target) {
useEventListener(moveTarget, 'mousedown', onMouseDown)
}
}
moveTarget 是鼠标点击的位置,target是要移动的部分。先注册一个 mousedown 事件 后续也就好说了
8个方向可拖拽
export interface windowDropOptions {
/**
* 是否可改变尺寸
*/
isResize: boolean,
/**
* 窗体最大高度
*/
maxHeight: number,
/**
* 窗体最大宽度
*/
maxWidth: number
}
export const WindowDrop = (target: MaybeRef<HTMLElement | null>, options: windowDropOptions) => {
const mouse = reactive(useMouseInElement(target))
/**
* 主窗体改变尺寸
* @param e
*/
const onMainMouseDown = (e: MouseEvent) => {
const targetRef = ref(target ?? window?.document.body)
const el = unrefElement(targetRef)
e.preventDefault()
if (!el)
return
//判断鼠标点击位置
const maxMargin = 7
const minMargin = -10
const mY = mouse.elementY
const mX = mouse.elementX
const xW = Math.abs(mouse.elementX - mouse.elementWidth)
const yH = Math.abs(mouse.elementY - mouse.elementHeight)
let disV = [0, 0]
//top
if (mY >= minMargin && mY <= maxMargin && mX >= maxMargin && xW >= maxMargin) {
disV = [-1, 0]
}
//bottom
if (yH >= minMargin && yH <= maxMargin && mX >= maxMargin && xW >= maxMargin) {
disV = [1, 0]
}
//left
if (mX >= minMargin && mX <= maxMargin && mY >= maxMargin && yH >= maxMargin) {
disV = [0, -1]
}
//right
if (xW >= minMargin && xW <= maxMargin && mY >= maxMargin && yH >= maxMargin) {
disV = [0, 1]
}
//left-top
if (mX >= minMargin && mX <= maxMargin && mY >= 0 && mY <= maxMargin) {
disV = [-1, -1]
}
//right-top
if (xW >= minMargin && xW <= maxMargin && mY >= 0 && mY <= maxMargin) {
disV = [-1, 1]
}
//left-bottom
if (mX >= minMargin && mX <= maxMargin && yH >= 0 && yH <= maxMargin) {
disV = [1, -1]
}
//right-bottom
if (xW >= minMargin && xW <= maxMargin && yH >= 0 && yH <= maxMargin) {
disV = [1, 1]
}
if (disV[0] === 0 && disV[1] === 0)
return
//鼠标点击位置X坐标
const disX = mouse.x
//鼠标点击位置Y坐标
const disY = mouse.y
//窗口的位置到顶的距离
const posT = el.offsetTop
//窗口的位置到左边的距离
const posL = el.offsetLeft
//窗口初始高度
const disH = el.offsetHeight
//窗口初始宽度
const disW = el.offsetWidth
//设置窗口可调的最小高度
const minH = 200
//设置窗口可调的最小宽度
const minW = 200
document.onmousemove = (e) => {
e.preventDefault()
//鼠标现在的位置
const nDisX = mouse.x
const nDisY = mouse.y
//移动后窗口的高度 //-1 * ( 当前鼠标Y - 鼠标初始位置Y ) + 窗口初始高度
let disNH = Math.max((disV[0] * (nDisY - disY) + disH), minH)
//移动后窗口的宽度 // 0 * ( 当前鼠标X - 鼠标初始位置X ) + 窗口初始宽度
let disNW = Math.max((disV[1] * (nDisX - disX) + disW), minW)
//移动后窗口顶到顶的距离// *(当前鼠标Y - 鼠标初始位置Y) + 窗口到顶的高度
let posNT = Math.min(disV[0], 0) * (disNH - disH) + posT
//移动后窗口到左边的距离//*(当前鼠标X - 鼠标初始位置X) + 窗口到左边的宽度
let posNL = Math.min(disV[1], 0) * (disNW - disW) + posL
//设置边界
posNT = Math.max(posNT, 0)
disNH = nDisY <= 0 ? disH + posT : disNH
disNH = nDisY > options.maxHeight ? options.maxHeight - posNT : disNH
disNW = Math.min(disNW, Math.abs(options.maxWidth - posNL))
//赋值
el.style.top = `${posNT}px`
el.style.left = `${posNL}px`
el.style.width = `${disNW}px`
el.style.height = `${disNH}px`
}
document.onmouseup = (e) => {
e.preventDefault()
document.onmousemove = null
document.onmouseup = null
}
}
if (target && options.isResize) {
useEventListener(target, 'mousedown', onMainMouseDown)
}
return {
mouse
}
}
mouse 使用了vueUse的useMouseInElement,大部分有注释,所以不难理解。首先就是要判段鼠标在目标的位置,然后来判断可拖动的方向(应该有更简洁的写法,可惜我不会,本想合并一下,但没下去手!!!)。默认将鼠标信息返回了,方便调试。
用法
使用起来还是比较简单的
<div ref='el'></div>
-------------------------------
import {PressDrop, WindowDrop} from '@/utils/WindowDrop'
const el = ref(null)
-------------------------------
PressDrop(move, el) // 窗体移动
/**
* 改变窗口大小
*/
WindowDrop(el, {isResize: true,maxHeight: 800,maxWidth: 1000})
最后
我应该可以称为非专业的程序员,所有技术全靠自学,纯纯的爱好。我本者不太深究,够用即可的方式,很多东西没学到位,仅够使用。所以以上代码中肯定有很多需要改的地方。这也是首次分享与大家。还请大家批评指正,我会虚心学习。