最近公司项目需要在H5页面上悬浮一个按钮,同时要求按钮是可以拖动的并且需要可以自动贴边,无奈前端小伙伴不怎么给力,无奈只能我顶上了。我觉得这种情况应该可以抽出一个组件,这次就仔细探讨一下悬浮按钮的实现原理吧。
因为平时我在开发过程中,手机端的开发我都推荐公司小伙伴使用uniapp进行,这次的自然也是在uniapp的环境下开发的组件,uniapp本身使用了小程序rpx作为单位。对于之前从来没使用过的小伙伴来说应该有点陌生,那我先解释一下这个rpx的单位是什么。
rpx单位一开始是微信小程序主推的,目的其实也很简单,因为手机屏幕有大有小,为了适应不同的屏幕才导致这个单位的出现。具体是这么定义的:
规定屏幕宽为750rpx。如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。
有了定义以后,也就有了计算的算法了,最终就得到了1rpx=0.5px,接下来就来说说悬浮按钮的实现过程吧。
首先,先使用一个view标签,也就是pc端的div,view是uniapp自己定义的一个标签,最终H5会编译成div小程序会编译成view。接下来自然就是view标签的css样式,其实也简单,因为整个view只是盒子而已。
整个盒子的z-index赋值为1000,也就浮在了最上层了。同时使用了固定定位整个盒子,因为之后要动态去修改整个盒子的位置,实现拖动效果。同时盒子使用flex布局,将内部的其他标签居中。我现在的做法是在内部放一个GIF图片,也算是满足需求了。
要怎么计算位置?一开始,我给view使用的是绝对定位,因此只需要将每次拖动图标是的x,y轴的位置动态赋值给整个view,那么就实现了移动,xy分别赋值给top和left。我们在手机端的时候H5view标签有几个方法我们可以使用,一个是touchmove一个是touchend。
touchmove方法就是手指按着view然后移动触发的方法,它有一个形参,形参有一堆参数,你看:
其实,我们只需要使用touches数据的第一个数据即可,这里的clientX就是x轴的值,clientY就是y轴的值。只要手指移动,这个函数就会被触发。因此我要去绑定这个方法,动态去修改top和left的值,动态给view的style赋值以后,自然它就跟着手指移动了。
当然,我在定义组件的时候还动态给整个组件赋值了一些margin-top的值什么的,自然是需要加上去的。最终实现的效果就是:
在移动view以后,万一用户将整个view移出了屏幕了怎么办?只要移出去以后就再也移不回来了。因此,就必须要说另一个方法touchend了。
touchend这个方法会在用户长按拖动并释放后触发,为了防止用户将整个view拖的无影无踪,因此必须要用户拖放结束后去人为计算用户的拖动是不是超出了边界,如果超出了边界就将top和left赋值成我们能接受的最大值。自然,在判断的过程中,要去计算X轴也必须计算Y轴,看是什么轴超出了就给置为最大的能接受值就能防止用户将整个view拖出视野,当然,我们在做着一切的时候必须要做一件事!那就是获取当前手机屏幕的xy的最大值,手机是有大有小,那怎么去获取呢?
我们使用uniapp的API:uni.getSystemInfoSync(),将整个屏幕的安全区域赋值给xy轴最大的能接受的值。
在touchend触发后这个函数也有个形参,参数和move是一样的,那么我们去计算就可以了
通过计算后复制,那么用户永远也不能将整个盒子拖出安全区域了。
最后说说贴边
因为就目前来说,需要贴边的其实也就贴左边或者贴右边。因此只需要在touchend函数中去判断,如果超过了屏幕宽度的一半那么就贴右边,小于一半就贴左边即可。