微信小程序中悬浮窗功能的实现代码(3)

当我们正常拖动悬浮窗时,通过catchtouchmove,我们可以捕获在悬浮窗上的滑动事件,并且不冒泡到父元素,那么我们绑在父层级的滑动事件就不会触发。

而当我们拖动在原生组件之上的悬浮窗时,因为点不到这个悬浮窗,就不会触发handleTouchMove函数,只会触发绑定在父元素上的handleSetMoveViewPos函数。

另外如果你细心的话,就会发现在handleSetMoveViewPos函数这里我缩小了那个60的缓冲区域为30,这样做的目的是因为触发这个函数只会在原生组件上,所以多番权衡距离之后,尽量避免近距离滑动操作就触发拖动悬浮框。

通过我们的方案,我们可以在非原生组件上自由拖动,在原生组件上比较顺畅地拖动。

本来我是准备将这个方案作为最终方案的,但是ios下,悬浮窗在原生组件上时,在父元素上的滑动事件竟然不触发。

棋差一招,棋差一招啊!

最终解决方案:更多的补丁,更多的快乐

这个最终解决方案,当然是把我们之前所有的补丁方案全部结合起来。

代码如下:

index.wxml: <view bindtouchmove="handleSetMoveViewPos"> <view wx-if="{{!isIos}}" bindtap="goToHome" catchtouchmove="handleTouchMove"> <image src="https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=4294841024,3545417298&fm=179&app=42&f=PNG?w=56&h=56"> </image> </view> <cover-view wx-if="{{isIos}}" bindtap="goToHome" catchtouchmove="handleTouchMove"> <cover-image src="https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=4294841024,3545417298&fm=179&app=42&f=PNG?w=56&h=56"> </cover-image> </cover-view> <textarea placeholder='我是textarea组件,用来输入一些信息'></textarea> <view> 一大段test,占个位,表示下存在感 </view> </view> index.js: Page({ /** * 页面的初始数据 */ data: { left: 20, top: 250, isIos: true }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { wx.getSystemInfo({ success: (res) => { if (res.platform == "android") { this.setData({ isIos: false }) } } }) }, /** * 拖拽移动(补丁) */ handleSetMoveViewPos: function (e) { // 在ios下永远都不会走这个方案,以免引起无用的计算 if (!ios) { const MOVE_VIEW_RADIUS = 30 // 悬浮窗半径 const touchPosX = e.touches[0].clientX const touchPosY = e.touches[0].clientY const moveViewCenterPosX = this.data.left + MOVE_VIEW_RADIUS const moveViewCenterPosY = this.data.top + MOVE_VIEW_RADIUS // 确保手指在悬浮窗上才可以移动 if (Math.abs(moveViewCenterPosX - touchPosX) < MOVE_VIEW_RADIUS && Math.abs(moveViewCenterPosY - touchPosY) < MOVE_VIEW_RADIUS) { if (touchPosX > 0 && touchPosY > 0) { this.setData({ left: touchPosX - MOVE_VIEW_RADIUS, top: touchPosY - MOVE_VIEW_RADIUS }) } else { this.setData({ left: 20, // 默认显示位置 left距离 top: 250 // 默认显示位置 top距离 }) } } } }, /** * 拖拽移动 */ handleTouchMove: function (e) { const MOVE_VIEW_RADIUS = 30 // 悬浮窗半径 const touchPosX = e.touches[0].clientX const touchPosY = e.touches[0].clientY if (touchPosX > 0 && touchPosY > 0) { this.setData({ left: touchPosX - MOVE_VIEW_RADIUS, top: touchPosY - MOVE_VIEW_RADIUS }) } else { this.setData({ left: 20, //默认显示位置 left距离 top: 250 //默认显示位置 top距离 }) } }, /** * 返回首页 */ goToHome: () => { wx.reLaunch({ url: '/pages/index/index', }) } })

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/796e68fd5c943f6976cba2147857ca6b.html