前言
收到需求,如图所示,能单项的调整
div
高度或宽度。注意使用 Vue2.x 开发。
效果
实现
Html
- 代码
7
和11
都监听mousedown
方法。
<template>
<div class="index">
<div class="win">
<!-- 移动面板 -->
<div id="pane" class="pane"></div>
<!-- 高度调整按钮:纵向滚动条 -->
<div class="resize-btn" @mousedown="onMouseDown($event, 'height')" >
<img src="/images/resize.png">
</div>
<!-- 宽度调整按钮:横向滚动条 -->
<div class="resize-h-btn" @mousedown="onMouseDown($event, 'width')" >
<img src="/images/resize-h.png">
</div>
</div>
</div>
</template>
JavaScript
只列出重点方法,完整代码在下一章节
- 代码
11
行,绑定mousemove
鼠标移动事件; - 代码
13
行,绑定mouseup
鼠标放开事件; - 代码
23/39
行,注意是使用documentElement
而不是body
; - 代码
23/25/39/41
行,减去的数值是根据当前<div id="pane" class="pane"></div>
相对于body
而计算得出的; - 代码
6/59
行,添加/移除 禁止用户选择网页中文字; - 代码
8/61
行,添加/移除 禁止用户拖动元素;
// 鼠标 down 事件监听
onMouseDown(event, type) {
// 当前类型
this.moveType = type;
// 禁止用户选择网页中文字
document.onselectstart = () => false
// 禁止用户拖动元素
document.ondragstart = () => false
// 绑定鼠标移动事件
document.addEventListener('mousemove', this.handleMouseMove)
// 绑定鼠标放开事件
document.addEventListener('mouseup', this.handleMouseUp)
},
// 鼠标 move 事件监听
handleMouseMove(event) {
const element = document.getElementById('pane');
// 设置高度
if(this.moveType === 'height') {
// 最小高度
const minHeight = 150;
// 最大高度: 注意这里是 documentElement,不能是 body
const maxHeight = document.documentElement.clientHeight - 100;
// 移动高度
let paneHeight = event.clientY-48;
// 限制最大最小
if(paneHeight < minHeight) {
paneHeight = minHeight;
}
else if(paneHeight > maxHeight) {
paneHeight = maxHeight;
}
element.style.height = `${paneHeight}px`;
}
else {// 设置宽度
// 最小宽度
const minWidth = 150;
// 最小宽度: 注意这里是 documentElement,不能是 body
const maxWidth = document.documentElement.clientWidth - 100;
// 移动宽度
let paneWidth = event.clientX - 36;
// 限制最大最小
if(paneWidth < minWidth) {
paneWidth = minWidth;
}
else if(paneWidth > maxWidth) {
paneWidth = maxWidth;
}
element.style.width = `${paneWidth}px`;
}
},
// 鼠标 up 事件监听
handleMouseUp() {
// 移除鼠标移动事件
document.removeEventListener('mousemove', this.handleMouseMove)
// 移除鼠标放开事件
document.removeEventListener('mouseup', this.handleMouseUp)
// 允许用户选择网页中文字
document.onselectstart = null
// 允许用户拖动元素
document.ondragstart = null
},
CSS
- 对移动按钮类名为
resize-btn
和resize-h-btn
都使用了 属性cursor
设置属性横向和纵向resize
效果;
.index {
padding: 20px;
}
.win {
position: relative;
top: 20px;
left: 20px;
display: inline-block;
.pane {
display: inline-block;
width: 250px;
height: 300px;
background: rgba(15,90,97,.8);
}
.resize-btn {
position absolute;
bottom: -10px;
width: 100%;
text-align: center;
cursor: n-resize;
}
.resize-h-btn {
display: inline-block;
position absolute;
right: -3px;
width: 10px;
height: 100%
cursor: e-resize;
img {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
}
}
完整代码
这是一个 *.vue
文件。
<template>
<div class="index">
<div class="win">
<!-- 移动面板 -->
<div id="pane" class="pane"></div>
<!-- 高度调整按钮:纵向滚动条 -->
<div class="resize-btn" @mousedown="onMouseDown($event, 'height')" >
<img src="/images/resize.png">
</div>
<!-- 宽度调整按钮:横向滚动条 -->
<div class="resize-h-btn" @mousedown="onMouseDown($event, 'width')" >
<img src="/images/resize-h.png">
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
// 移动类型:width 宽度,height 高度
moveType: 'height',
}
},
methods: {
// 鼠标 down 事件监听
onMouseDown(event, type) {
// 当前类型
this.moveType = type;
// 禁止用户选择网页中文字
document.onselectstart = () => false
// 禁止用户拖动元素
document.ondragstart = () => false
// 绑定鼠标移动事件
document.addEventListener('mousemove', this.handleMouseMove)
// 绑定鼠标放开事件
document.addEventListener('mouseup', this.handleMouseUp)
},
// 鼠标 move 事件监听
handleMouseMove(event) {
const element = document.getElementById('pane');
// 设置高度
if(this.moveType === 'height') {
// 最小高度
const minHeight = 150;
// 最大高度: 注意这里是 documentElement,不能是 body
const maxHeight = document.documentElement.clientHeight - 100;
// 移动高度
let paneHeight = event.clientY-48;
// 限制最大最小
if(paneHeight < minHeight) {
paneHeight = minHeight;
}
else if(paneHeight > maxHeight) {
paneHeight = maxHeight;
}
element.style.height = `${paneHeight}px`;
}
else {// 设置宽度
// 最小宽度
const minWidth = 150;
// 最小宽度: 注意这里是 documentElement,不能是 body
const maxWidth = document.documentElement.clientWidth - 100;
// 移动宽度
let paneWidth = event.clientX - 36;
// 限制最大最小
if(paneWidth < minWidth) {
paneWidth = minWidth;
}
else if(paneWidth > maxWidth) {
paneWidth = maxWidth;
}
element.style.width = `${paneWidth}px`;
}
},
// 鼠标 up 事件监听
handleMouseUp() {
// 移除鼠标移动事件
document.removeEventListener('mousemove', this.handleMouseMove)
// 移除鼠标放开事件
document.removeEventListener('mouseup', this.handleMouseUp)
// 允许用户选择网页中文字
document.onselectstart = null
// 允许用户拖动元素
document.ondragstart = null
},
}
}
</script>
<style lang="stylus" scoped>
.index {
padding: 20px;
}
.win {
position: relative;
top: 20px;
left: 20px;
display: inline-block;
.pane {
display: inline-block;
width: 250px;
height: 300px;
background: rgba(15,90,97,.8);
}
.resize-btn {
position absolute;
bottom: -10px;
width: 100%;
text-align: center;
cursor: n-resize;
}
.resize-h-btn {
display: inline-block;
position absolute;
right: -3px;
width: 10px;
height: 100%
cursor: e-resize;
img {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
}
}
</style>