<template>
<div>
<div class="short-box" v-if="path != '/login'" ref="shortList">
<div class="short-btn customer-service" @click="showMask = !showMask" ref="customerService"
@touchstart="!showMask && touchstartHandle('customerService',$event)"
@touchmove="!showMask && touchmoveHandle('customerService',$event)"
@touchend="!showMask && end('customerService')">
<div class="short-list" :class="{ show: showMask, classFlag: classFlag, topPos: !classFlag}">
<div class="short-item">
<p><van-icon class="iconfont icon-shouye" /></p>
<p>首页</p>
</div>
<div class="short-item">
<p><van-icon class="iconfont icon-xinjian" /></p>
<p>新建</p>
</div>
<div class="short-item">
<p><van-icon class="iconfont icon-qiehuan" /></p>
<p>切换</p>
</div>
<div class="short-item">
<p><van-icon class="iconfont icon-fanhui" /></p>
<p>返回</p>
</div>
</div>
<van-icon class="iconfont" :class="{ 'icon-guanbi1': showMask, 'icon-caidan1': !showMask }" />
</div>
</div>
</div>
</template>
以上为HTML代码里面带有可展开的操作项,项目中用到了vant框架,和阿里的字体图标
.customer-service{
position: fixed;
right: 20px;
width: 88px;
bottom: 180px;
z-index: 99;
}
.short-btn {
width: 88px;
height: 88px;
border-radius: 50%;
text-align: center;
background: linear-gradient(321deg, #4575F4 0%, #5B85F2 30%, #79C1FF 100%);
box-shadow: 0px 3px 5px 0px #B4C8FF;
position: fixed;
display: flex;
justify-content: center;
align-items: center;
i {
font-size: 44px;
border-radius: 50%;
color: #fff;
&.icon-guanbi1 {
font-size: 30px;
}
}
}
.short-list {
width: 88px;
background: #E0EBF7;
border-radius: 48px;
margin-bottom: 20px;
box-sizing: border-box;
min-height: 0px;
max-height: 0px;
overflow: hidden;
transition: max-height ease-out 0.2s;
position: absolute;
&.topPos{
bottom: 88px;
}
&.classFlag{
top: 100px;
}
.short-item {
text-align: center;
padding: 24px 0;
p {
font-size: 20px;
color: #999999;
margin: 0;
line-height: 20px;
i {
font-size: 44px;
color: #0179FF;
margin-bottom: 10px;
}
}
+.short-item {
border-top: 1px solid #C4D3E4;
}
}
&.show {
max-height: 500px;
transition: max-height ease-out 0.2s;
}
}
由于拖拽按钮需要根据悬浮按钮的定位上面展开或者悬浮按钮下面展开,所以需要设置不同的定位方式,根据类名topPos或者classFlag类名定义不同的定位方式。
<script>
export default {
data() {
return {
touch: {
initialPosition: {
x: 0,
y: 500
},
movePostion: {}
},
element: {
initialPosition: {},
movePostion: {}
},
nowLeft: -1,
classFlag: false
}
},
methods:{
touchstartHandle (refName, e) {
// 触摸开始
let touchTarget = e.targetTouches[0];
// 记录触摸点的坐标(初始位置)
this.touch.initialPosition = {
x: touchTarget.clientX,
y: touchTarget.clientY
}
// 记录需要移动的元素坐标(初始位置)
this.element.initialPosition = {
x: this.$refs[refName].offsetLeft,
y: this.$refs[refName].offsetTop
}
},
touchmoveHandle (refName, e) {
e.preventDefault();
let touchTarget = e.targetTouches[0];
let X = this.element.initialPosition.x + (touchTarget.clientX - this.touch.initialPosition.x);
let Y = this.element.initialPosition.y + (touchTarget.clientY - this.touch.initialPosition.y);
let maxWidth = innerWidth - this.$refs[refName].offsetWidth;
let maxHeight = innerHeight - this.$refs[refName].offsetHeight;
X = X <= 0 ? 0 : X >= maxWidth ? maxWidth : X;
Y = Y <= 0 ? 0 : Y >= maxHeight ? maxHeight : Y;
this.nowLeft = X;
this.classFlag = Y < 300
// 移动元素
this.$refs[refName].style.left = X + 'px'
this.$refs[refName].style.top = Y + 'px';
},
end (refName) {
if (this.nowLeft < 0) {
return;
}
// 吸边处理
let halfMaxWidth = (innerWidth - this.$refs[refName].offsetWidth) / 2;
const dragDiv = this.$refs[refName];
if (this.nowLeft> halfMaxWidth) {
// 右吸边
dragDiv.style.left = document.documentElement.clientWidth - parseInt(dragDiv.clientWidth) -10 + 'px';
}
else {
// 左吸边
dragDiv.style.left = "10px";
}
dragDiv.style.top = dragDiv.offsetTop + 'px';
},
}
}
</script>