<template>
<div
ref="floatTab"
class="float-tab"
:style="{
top: top + 'px',
left: left + 'px',
}"
@mousedown="handleMousedown"
>
拖拽组件
</div>
</template>
<script>
// 距离窗口上下边的距离
const fixedDirection = 50;
// 距离右侧的固定距离
const fixedRightDirection = 18;
export default {
name: 'float-tab',
props: {},
data() {
return {
/** 距离窗口头部的距离 */
top: 0,
/** 距离窗口右侧的距离 */
left: 0,
/** 组件的拖拽状态 */
dragStatus: false,
/** 组件的高度 */
height: 0,
/** 组件的宽度 */
width: 0,
/** 鼠标点击的时候距离内容顶部的高度 */
mouseStartTop: 0,
/** 鼠标点击的时候距离内容左侧的高度 */
mouseStartLeft: 0,
/** 窗口的高度 */
clientHeight: 0,
/** 窗口的宽度 */
clientWidth: 0,
};
},
created() {
//进入页面获取窗口宽高
this.clientHeight = document.documentElement.clientHeight;
this.clientWidth = document.documentElement.clientWidth;
},
mounted() {
// 当窗口的大小发生变化时,主要用于pc端
window.addEventListener('resize', this.resizeFuc);
this.$once('hook:beforeDestroy', () => {
window.removeEventListener('mousemove', this.handleMousemove);
window.removeEventListener('mouseup', this.handleMouseup);
window.removeEventListener('resize', this.resizeFuc);
});
this.$nextTick(() => {
// 获取拖动部分的宽高
setTimeout(() => {
let floatTab = this.$refs.floatTab;
this.height = floatTab?.clientHeight:100;
this.width = floatTab?.clientWidth:50;
this.top = this.clientHeight - fixedDirection - this.height;
// 开始时的距离左侧的距离为窗口宽度-右侧距离-自身宽度
this.left = this.clientWidth - fixedRightDirection - this.width;
});
});
},
methods: {
/** 窗口尺寸发生变化时,防止拖拽的内容被隐藏,能一直显示在页面中 */
resizeFuc() {
this.clientHeight = document.documentElement.clientHeight;
this.clientWidth = document.documentElement.clientWidth;
// 当竖直方向上窗口的尺寸发生变化,会掩盖住内容的时候、
if (this.top + this.height + fixedDirection > this.clientHeight) {
// 重新计算距离顶部的高度
this.top = this.clientHeight - this.height - this.mouseStartTop;
console.log('窗口尺寸发生变化', this.top);
}
// 当水平方向上窗口的尺寸发生变化,会掩盖住内容的时候、
if (this.left + this.width + fixedRightDirection !== this.clientWidth) {
// 重新计算距离顶部的高度
this.left = this.clientWidth - this.width - fixedRightDirection;
console.log('窗口尺寸发生变化', this.left);
}
},
/** 释放鼠标,拖动结束*/
handleMouseup() {
//解除在window上的监听
window.removeEventListener('mousemove', this.handleMousemove);
window.removeEventListener('mouseup', this.handleMouseup);
console.log('释放鼠标');
this.dragStatus = false;
// 松开鼠标内容自动贴在右侧
this.left = this.clientWidth - this.width - fixedRightDirection;
},
/** 鼠标拖动,更改组件内容位置 */
handleMousemove(e) {
let clientY = e.clientY;
let clientX = e.clientX;
// 计算距离顶部的高度
if (
this.dragStatus &&
clientY + this.height + fixedDirection < this.clientHeight &&
clientY - this.mouseStartTop > fixedDirection
) {
// 判断当前的位置
this.top = clientY - this.mouseStartTop;
}
// 计算距离左侧的距离
if (
this.dragStatus &&
clientX - this.mouseStartLeft > 0 &&
this.clientWidth - clientX + this.mouseStartLeft >
this.width + fixedRightDirection
) {
this.left = clientX - this.mouseStartLeft;
}
},
/** 按下鼠标开始拖动 */
//注意在使用的时候再往window上绑定鼠标事件,这样减少性能消耗
handleMousedown(e) {
// dom中mouseup脱离元素后无法触发,所以要把 mouseup 事件挂载到全局或者 document 上即可
window.addEventListener('mousemove', this.handleMousemove);
window.addEventListener('mouseup', this.handleMouseup);
console.log('按下鼠标', e.clientY, this.top);
this.dragStatus = true;
this.mouseStartTop = e.clientY - this.top;
this.mouseStartLeft = e.clientX - this.left;
},
},
};
</script>
<style lang="less" scoped>
.float-tab {
position: fixed;
width: 50px;
height: 100px;
background: red;
}
</style>
网友评论