移动端H5的悬浮按钮(可拖动)
程序员文章站
2024-03-15 23:09:12
...
今天工作时遇到了一个需求,要去做一个可拖动的悬浮按钮。
查找了资料发现了一个文章然后根据内容进行修改。
添加链接描述
效果图大概是这个样子,然后可以在界面上拖动。
因为是taro的项目,所以下面的代码是基于taro实现的,最后边会给出原生js的实现代码,如果有错误的地方希望指正出来进行修改。
首先是render部分,
拖动的事件分布为:onTouchStart(开始拖动执行的事件),onTouchMove(拖动时执行的事件),onTouchEnd(拖动结束执行的事件)
首先先给view设置固定定位fixed,然后通过控制left和top的属性来设置位置
render() {
return (
<View
className="t-suspend-button"
onClick={this.handleClick.bind(this)}
onTouchStart={e => this.onTouchStart(e)}
onTouchMove={e => this.onTouchMove(e)}
onTouchEnd={e => this.onTouchEnd(e)}
style={{
position: fixed;
left: `${this.state.oLeft}px`,
top: `${this.state.oTop}px`
}}
>
<Image src='自己写图片路径' className='customer-logo' />
<View className='customer-text'>在线客服</View>
</View>
)
}
//先定义一些变量
constructor(props) {
super(props)
this.state = {
oLeft: 0,
oTop: 0,
}
this.oDiv = null
this.disX = null
this.disY = null
this.moveX = null
this.moveY = null
this.L = null
this.T = null
this.starX = null
this.starY = null
this.starXEnd = null
this.starYEnd = null
}
//在这个生命周期函数里定义oDiv 还有初始的位置
componentDidMount() {
this.oDiv = document.getElementsByClassName('t-suspend-button')[0];
this.setState({
oTop:document.documentElement.clientWidth +this.oDiv.offsetHeight
})
}
//点击事件
enquire(e){
e.preventDefault();
console.log(11111)
}
onTouchStart(e) {
// e.preventDefault();
this.disX = e.touches[0].clientX - this.oDiv.offsetLeft;
this.disY = e.touches[0].clientY - this.oDiv.offsetTop;
//手指按下时的坐标
this.starX = e.touches[0].clientX;
this.starY = e.touches[0].clientY;
}
onTouchMove(e) {
this.L = e.touches[0].clientX - this.disX;
this.T = e.touches[0].clientY - this.disY;
//移动时 当前位置与起始位置之间的差值
this.starXEnd = e.touches[0].clientX - this.starX;
this.starYEnd = e.touches[0].clientY - this.starY;
//console.log(L);
if (this.L < 0) {//限制拖拽的X范围,不能拖出屏幕
this.L = 0;
} else if (this.L > document.documentElement.clientWidth - this.oDiv.offsetWidth) {
this.L = document.documentElement.clientWidth - this.oDiv.offsetWidth;
}
if (this.T < 0) {//限制拖拽的Y范围,不能拖出屏幕
this.T = 0;
} else if (this.T > document.documentElement.clientHeight - this.oDiv.offsetHeight) {
this.T = document.documentElement.clientHeight - this.oDiv.offsetHeight;
}
this.moveX = this.L ;
this.moveY = this.T;
this.setState({
oLeft: this.moveX,
oTop: this.moveY
})
}
onTouchEnd(e){
//计算结束的位置是靠左还是靠右
let oLeft = this.state.oLeft
if(oLeft < (document.documentElement.clientWidth - this.oDiv.offsetWidth)/2){
oLeft = 0
}else{
oLeft = document.documentElement.clientWidth - this.oDiv.offsetWidth
}
this.setState({
oLeft:oLeft
})
}
上面就是taro的代码可以实现拖动效果的悬浮按钮。
下面是原生JS实现
<style>
* {
margin: 0;
padding: 0;
}
.btn {
width: 50px;
height: 50px;
background-color: blue;
position: fixed;
}
</style>
<body>
<div>
<div id='btn' class="btn"></div>
</div>
</body>
<script>
window.onload = function () {
var oDiv = document.getElementById('btn');
var disX,disY, moveX,moveY, L, T, starX, starY, starXEnd, starYEnd;
oDiv.addEventListener('touchstart', function(e) {
// e.preventDefault();//阻止触摸时页面的滚动,缩放
oDiv.style.left = moveX + 'px';
oDiv.style.top = moveY + 'px';
disX = e.touches[0].clientX - this.offsetLeft;
disY = e.touches[0].clientY - this.offsetTop;
//手指按下时的坐标
starX = e.touches[0].clientX;
starY = e.touches[0].clientY;
//console.log(disX);
});
oDiv.addEventListener('touchmove', function(e) {
L = e.touches[0].clientX - disX;
T = e.touches[0].clientY - disY;
//移动时 当前位置与起始位置之间的差值
starXEnd = e.touches[0].clientX - starX;
starYEnd = e.touches[0].clientY - starY;
//console.log(L);
if (L < 0) {//限制拖拽的X范围,不能拖出屏幕
L = 0;
} else if (L > document.documentElement.clientWidth - this.offsetWidth) {
L = document.documentElement.clientWidth - this.offsetWidth;
}
if (T < 0) {//限制拖拽的Y范围,不能拖出屏幕
T = 0;
} else if (T > document.documentElement.clientHeight - this.offsetHeight) {
T = document.documentElement.clientHeight - this.offsetHeight;
}
moveX = L ;
moveY = T ;
//console.log(moveX);
oDiv.style.left = moveX + 'px';
oDiv.style.top = moveY + 'px';
});
oDiv.addEventListener('touchend', function(e) {
if(moveX < (document.documentElement.clientWidth - oDiv.offsetWidth)/2){
moveX = 0
}else{
moveX = document.documentElement.clientWidth - oDiv.offsetWidth
}
oDiv.style.left = moveX + 'px';
});
}
</script>