这是目前最近开发的一个小程序完成后的一些心得。
- 需求是有一张静态地图,用户点击对应的县要进入二级页面,
- 二级页面里面底图是一张静态地图,上面展示出相应的景点。点击景点显示景点简介
- 一级页面和二级页面都是可以拖动和缩放的,双击可以缩放
具体功能页如下:
我先是通过自己写touch事件体验,使用正常的h5测试已经能明显感觉到体验不是很流畅。
改写成小程序,滑动数据都是用setData,本身又有个延迟操作。体验后发现效果非常之差劲,卡顿现象特别严重。放弃了该方案!
后来发现小程序有提供movable-area和movable-view的拖动组件,尝试写了个demo,体验后拖动缩放流畅,效果流畅,我想没跑了这就是我想要的。
不过真正开发后发现还有很多问题需要解决,具体如下:
没有事件监听用户是否结束了拖动和缩放。
移动端是没有双击事件的,如何解决
transform-scale用于缩放元素的话,会导致子元素被等比例缩放了,如何解决
如何判断用户点击那个区块,进而跳转二级页面做出不同的响应
接下来,我们来一一解决上面的几个问题!
问题1: 没有事件监听用户是否结束了拖动和缩放?
我们可以通过touchend事件来兼听用户手指是否离开屏幕从而知道用户是否停止了拖动和缩放操作。
但是,但是,如果我是通过代码控制滑动和缩放的情况下又要怎么监听呢???这里从一位做IOS工程师的同事那里得到一个很巧妙的解决方案。具体看如下代码:
扫描二维码关注公众号,回复: 5755929 查看本文章
//微信自带生命周期
onLoad(options){
this.checkAnimalEnd=true;//开启检查功能
this.setData({
scale: 2//将movable-view自动放大两倍
})
},
//movable-view自带监听缩放事件
onScale(e){
//只有是自动设置缩放的情况才需要检查
if(this.checkAnimalEnd){
this.closeTimer();//每次缩放回调先关闭定时器
this.timer();//开启定时器
}
//do something
...
},
//关闭定时器
closeTimer() {
if (this.intervalTimer) clearInterval(this.intervalTimer);
},
//定时器检测缩放和拖动是否结束
timer() {
//使用interval定时器
this.intervalTimer = setInterval(()=>{
console.log('setInterval');
this.closeTimer();
//do something
....
}, 500);
},
问题2: 移动端是没有双击事件的,如何解决?
这个网络上都有很多种方案了,现在我是使用下面这种方式实现的,同上面的定时器方案类似,就是给单击事件挂载到一个延时器中,然后在检查到用户进行了双击操作就取消单击事件延时器。否则就执行单击事件,具体代码如下:
//params.oneTap=》执行单击事件
//params.dbTap =》执行双击事件
checkTap(params = {}) {
let nowTime = new Date().getTime();
if (nowTime - this.lastClickTime < 300) {
/*双击*/
this.lastClickTime = 0;
this.clickTimer && clearTimeout(this.clickTimer);
console.log('双击');
typeof params.dbTap === 'function' && params.dbTap();
} else {
/*单击*/
this.lastClickTime = nowTime;
this.clickTimer = setTimeout(() => {
console.log('单击');
typeof params.oneTap === 'function' && params.oneTap();
}, 300);
}
},
//点击moveable-view事件
onTap(e) {
let that = this;
this.checkTap({
//oneTap: a => { this.oneTap(e) },
dbTap: this.dbTap
});
},
问题3: transform-scale用于缩放元素的话,会导致子元素被等比例缩放了,如何解决?
这个确实困扰了我好久,一开始是给子元素设置了初始尺寸,然后缩放后,针对width和height进行计算。结果不太理想。后来同样是使用transform-scale反向缩放回去了。具体做法如下:
<!--注意看{{这里的写法}}-->
<movable-area style="width: 100%;height:100%;">
<movable-view style="width: 1500px;height: 1500px;" scale scale-min="0.5" scale-max="2" scale-value="{{scale}}">
<view style="transform: scale({{1/scale}});">我是子元素啊</view>
</movable-view>
</movable-area>
问题4: 如何判断用户点击那个区块,进而跳转二级页面做出不同的响应?
这个其实就是判断下用户点击的位置是否在一个多边形内。
具体原理这里不做讨论了,在网上找到一个讲的很不错的博客,我用的就是方案1,请认真看下原理在翻到第二篇看源码。
指路=》https://blog.csdn.net/u283056051/article/details/53980832
因此,我们要做的就是将图片中每个不规则版块的临界点位置描出来存储在一个二维数组即可解决。
以上,是我在开发该小程序中遇到的几个我自己感觉比较有难度的问题以及解决方案,如果你有不同的解决方案,欢迎留言告知。
最后,谢谢阅读!