前言
找了许多关于鼠标拖动改变页面两个盒子宽度的方式,感觉效果都不是很理想,所以记录一下。
一.封装 vue 自定义指令的方式
代码如下(示例):
import Vue from 'vue'
import { EventListener } from '@/utils/index'
//引入 EventListener 自定义监听事件方法,写法在我另一篇文章
Vue.directive('elResize', {
inserted(el, binding, vnode) {
const container = el.parentNode
const left = container.children[0]
const right = container.children[container.children.length - 1]
let documentMousemoveEvent = null
let documentMouseupEvent = null
el.addEventListener('mousedown', function (e) {
container.style.userSelect = 'none'
container.style.cursor = 'col-resize'
let startX = e.clientX
let containerOffsetWidth = parseInt(getComputedStyle(container).width)
let elOffsetLeft = el.offsetLeft
documentMousemoveEvent = EventListener.listen(document, 'mousemove', mousemoveEvent => {
var endX = mousemoveEvent.clientX
var moveLen = elOffsetLeft + (endX - startX) // (endx-startx)=移动的距离。
var maxT = containerOffsetWidth - el.offsetWidth // 容器宽度 - 左边区域的宽度 = 右边区域的宽度
if (moveLen < 700) moveLen = 700 // 左边区域的最小宽度为700px
if (moveLen > maxT - 280) moveLen = maxT - 280 //右边区域最小宽度为280px
el.style.left = moveLen
left.style.width = moveLen + 'px'
right.style.width = (containerOffsetWidth - moveLen - 10) + 'px'
})
documentMouseupEvent = EventListener.listen(document, 'mouseup', mouseupEvent => {
container.style.userSelect = 'unset'
container.style.cursor = 'unset'
if (documentMousemoveEvent) documentMousemoveEvent.remove()
if (documentMouseupEvent) documentMouseupEvent.remove()
el.releaseCapture && el.releaseCapture() //当你不在需要继续获得鼠标消息就要应该调用ReleaseCapture()释放掉
})
el.setCapture && el.setCapture() //该函数在属于当前线程的指定窗口里设置鼠标捕获
return false
})
}
})
二.使用方式
代码如下(示例):
<template>
<div class="common-layout" style="width:100%;">
<div class="common-layout-left ">
左侧盒子
</div>
<div class="resize" v-el-resize></div>//自定义 v-el-resize 指令绑定在中间可拖动区域
<div class="common-layout-right ">
右侧盒子
</div>
</div>
</template>
<style lang="scss" scoped>
.resize{
width: 5px;
cursor: col-resize;
}
</style>