背景
项目中引入了百度地图,但发现地图的 click 事件在 H5 没反应,查找一番发现原因是在移动端百度地图不支持 click 事件。
touchstart 与 touchend
那么就需要使用 TouchEvent 来实现,因为要区分点击、滑动、缩放,需要通过计算触屏位移和持续时间来判断是不是点击,监听 touchstart 记录触屏起始位置和开始时间,监听 touchend 计算触屏从开始到离开的位移和时长,一般来说时长很短(小于300ms)且位移为0(即起始位置和离开位置在一个点)才是点击,但考虑到某些机型可能会有细微偏移,可以允许一定的误差。
renderBMap() {
// 实例化地图
this.bmap = new window.BMap.Map('bmap-container')
// 区分点击、滑动和缩放事件
let time, startX, startY
this.bmap.addEventListener('touchstart', e => {
// 记录触屏起始位置和开始时间
time = Date.now()
startX = e.targetTouches[0].pageX
startY = e.targetTouches[0].pageY
})
this.bmap.addEventListener('touchend', e => {
// 计算触屏从开始到离开的位移和时长
const endX = e.changedTouches[0].pageX
const endY = e.changedTouches[0].pageY
if (
Date.now() - time < 300 &&
Math.abs(endX - startX) < 5 &&
Math.abs(endY - startY) < 5
) {
// 点击地图
this.bmap.clearOverlays()
const bPoint = new window.BMap.Point(e.point.lng, e.point.lat)
this.bmap.addOverlay(new window.BMap.Marker(bPoint))
const convertor = new window.BMap.Convertor()
// 5-百度坐标(bd09ll)转 3-火星坐标(gcj02)
convertor.translate([bPoint], 5, 3, data => {
doSomething(data.points[0].lat, data.points[0].lng)
})
}
})
}
targetTouches 与 changedTouches
- touches:当前屏幕上所有触摸点的列表
- targetTouches:当前对象上所有触摸点的列表
- changedTouches:涉及当前(引发)事件的触摸点的列表
- touchstart 和 touchmove 使用:e.targetTouches[0].pageX
- touchend 使用:e.changedTouches[0].pageX