由于项目需要,想要在某个页面实现一个类似iPhone悬浮按钮的功能。
在之前的提问里(链接:div 设置了touchmove ,结果overflow 不生效了),有写到关于按钮上下移动的样式,现在完善左右移动的切换以及对应样式的改变。
HTML代码:
<template>
<div style=" touch-action: none;">
<div id="divMove" :class="!isClick && 'divMove' " @click="handleStretch"
@mousedown="down" @touchstart="down"
@mousemove="move" @touchmove.prevent="move"
@mouseup="end" @touchend="end"
>
</div>
<div id="stretchBtn" :class="positionNow =='right'? 'stretchBtn showStyle' : 'stretchBtn showStyleLeft'" >
<div id="iconImg" class="iconImg" >
<div v-if="!isClick" id="imgM">
<div id="backBtn" :class="positionNow =='right'? 'backBtn' : 'backBtnLeft' "></div>
<div id="backBtnM" class="backBtnM" :style="positionNow =='right'? 'margin-left:15px' : 'margin-left:30px; transform: rotateY(0) ' "></div>
</div>
</div>
<div v-if="isClick" :class="positionNow =='right'? 'toIndex' : 'toIndexLeft'" >
<img src="../assets/img/zhuye.png" width="100%" height="35px">
</div>
<div v-if="isClick" id="lineImg" class="lineImg" :style="positionNow ==='right'? 'margin-right: 5px' : 'margin-right: 5px' ">
<div v-for="(item, index) in imgSrc" :key="index" class="divBorder imgSpacing">
<img :src="item.icon" width="30px" height="30px" style="border-radius:5px">
</div>
</div>
<div v-if="isClick" id="shouqi" :class="positionNow =='right'? 'shouqi' : 'shouLeft'" >
<img :src="positionNow === 'right' ? require('../assets/img/shouqi.png') : require('../assets/img/shouLeft.png')"
alt="" width="10px" height="20px" @click="handleStretch" />
</div>
</div>
</div>
</template>
一开始想要通过 document.getElementById() 去更改样式,但是在切换的时候,会造成延迟。于是采用了 v-bind 判断当前悬浮按钮位置,进而渲染不同的样式。
JavaScript代码:
// 实现移动端拖拽
down(e){
this.flags = true;
let touch;
const odiv = e.target;
event.touches ? touch = event.touches[0] : touch = event;
this.position.y = touch.clientY;
this.position.x = touch.clientX;
this.dy = odiv.offsetTop;
this.dX = odiv.offsetLeft;
const objImgM = document.getElementById('imgM');
objImgM && (objImgM.style.opacity = '1');
},
move(e){
if(this.flags){
let touch ;
const objStratch = document.getElementById('stretchBtn');
const objIconImg = document.getElementById('iconImg');
const odiv = e.target;
event.touches ? touch = event.touches[0] : touch = event;
this.ny = touch.clientY - this.position.y;
this.nx = touch.clientX - this.position.x;
this.yPum = this.dy+this.ny;
this.XPum = this.dX+this.nx;
odiv.style.top = this.yPum +"px";
objStratch.style.top = this.yPum +"px";
odiv.style.left = this.XPum +"px";
objIconImg.style.left = this.XPum +"px";
// 阻止页面的滑动默认事件;如果碰到滑动问题,1.2 请注意是否获取到 touchmove
document.addEventListener('touchmove', function(event) {
// 判断默认行为是否可以被禁用
if (event.cancelable) {
// 判断默认行为是否已经被禁用
if (!event.defaultPrevented) {
event.preventDefault();
}
}
}, false);
}
},
// 鼠标释放时候的函数
end(e){
this.flags = false;
const objImgM = document.getElementById('imgM');
objImgM && (objImgM.style.opacity = '0.7');
// 判断 左右移动
if(this.XPum){
// 移动之后才会有值。
this.XPum < (window.screen.width / 2 ) ? this.positionNow = 'left' : this.positionNow = 'right';
}
this.setBtnPosition();
},
setBtnPosition() {
const objStratch = document.getElementById('stretchBtn');
const objMove = document.getElementById('divMove');
const objIconImg = document.getElementById('iconImg');
if(this.positionNow === 'left'){
// console.log('在左侧~~~~~~')
objMove.style.left = '0';
objStratch.style.left = '0';
objIconImg.style.left = '0';
}else{
const positionMove = window.screen.width - 70;
const positionIconImg = window.screen.width - 70;
const positionStratch = window.screen.width - 190;
objMove.style.left = `${positionMove}px`;
objStratch.style.left = `${positionStratch}px`;
objIconImg.style.left = `${positionIconImg}px`;
}
},
其中,跟之前的上下移动多了一点的地方是
1,X轴的位置变化,及其赋值。如下所示:
//down(e)
this.dX = odiv.offsetLeft;
// move(e)
this.XPum = this.dX+this.nx;
odiv.style.left = this.XPum +"px";
objIconImg.style.left = this.XPum +"px";
2,按钮半透明样式切换
默认值为:0.7,点下 为1 ,松开变回0.7
// down(e)
const objImgM = document.getElementById('imgM');
objImgM && (objImgM.style.opacity = '1');
// move(e)
const objImgM = document.getElementById('imgM');
objImgM && (objImgM.style.opacity = '0.7');
3,左右位置的判断,主要就是 setBtnPosition() 这个方法。
当在右边的时候,直接获取屏幕宽度 减去 当前div的宽度。
之前有想要去除 left,设置 right=0,但是没有生效。于是改用这个方法,若有知道的,麻烦留言一下。让我多学学。
css代码:
.stretchBtn {
position: fixed;
top: 0;
right: 0;
display: flex;
flex-direction: row-reverse;
z-index: 1000;
max-height: 100px;
}
.iconImg{
position: fixed;
display: flex;
flex-direction: row-reverse;
justify-content: center;
}
#imgM{
opacity: 0.7;
width: 60px;
}
.backBtnM{
height: 30px;
background: url('~/assets/img/gamePlay/icon2.png') no-repeat;
background-size: 25px 25px;
margin-top: -40px;
margin-left: 15px;
}
.backBtn{
width: 70px;
height: 48px;
background: url('~/assets/img/gamePlay/back-btn2.png') no-repeat;
background-size: 237%;
}
.backBtnLeft{
width: 70px;
height: 48px;
background: url('~/assets/img/gamePlay/back-btn2.png') no-repeat;
background-size: 237%;
transform: rotateY(180deg);
}
.showStyle{
width: 195px;
background: url('~/assets/img/gamePlay/back-btn2.png') no-repeat;
background-size: 100% 50px;
}
.showStyleLeft{
width: 195px;
background: url('~/assets/img/gamePlay/back-btn.png') no-repeat;
background-size: 100% 50px;
}
.lineImg{
display: flex;
flex-direction: row-reverse;
overflow-x: auto;
height: 50px;
margin-top: 8px;
z-index: 1999;
}
.lineImg::-webkit-scrollbar { width: 0 !important }
.imgSpacing{
padding: 0 3px;
}
.divMove{
position: fixed;
right: 0;
width:70px;
height: 43px;
background-color: rgba(214, 106, 106, 0);
z-index: 1999;
}
.shouqi{
display: flex;
justify-content: center;
align-items: center;
margin-right: 5px;
height: 50px;
margin-top:-2px
}
.shouLeft{
display: flex;
justify-content: center;
align-items: center;
margin-right: -128px;
height: 50px;
margin-top:-2px
}
.toIndex{
margin-top: 5px;
margin-right: 15px;
}
.toIndexLeft{
position: relative;
left: -150px;
margin-top: 5px;
}
关于有些图片的位置,直接采用了margin 负值和 定位走的。感觉不是很好,希望看到文章的各路好汉多支支招。在此谢过了。
到此,悬浮按钮的样式算是完成了。
效果图:
就参考你们自己手机上的悬浮按钮吧,嘻嘻。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。