问题

今天写了一个小画板网页程序,在电脑浏览器上测试没有问题,然而手机端却无法正常使用。

分析

具体表现为,手机端尝试在画板上绘图时,会优先触发画面移动/缩放,而画板是基于mousemove事件的,这导致触屏无法正常使用画板。

其实,据MDN文档, 很多情况下,TouchEvent和MouseEvent会一起触发以使非触摸专用的代码仍然可以与用户交互。然而,阻挡我们的首先是默认事件之画面移动。

一开始,我尝试直接对TouchEvent调用preventDefault()。结果画面移动不再触发,但触屏事件伴生的鼠标事件也被阻挡了,鉴于画板程序仅识别MouseEvent,移动端仍然无法使用画板。

解决方案

preventDefault( )阻止触屏的默认事件后,再手动模拟触发一个鼠标事件。

这里用一个"map"将常用的三种触屏事件映射为了模拟的鼠标事件,然后在dom上使用dispatchEvent()来触发模拟的鼠标事件。

(这里的canvasObj是一个HTML canvas元素)

//加入对触屏的支持
    const touchToMouse = {
      'touchstart': 'mousedown',
      'touchend': 'mouseup',
      'touchmove': 'mousemove'
    }

    for (let touchEvent in touchToMouse) {

      canvasObj.addEventListener(touchEvent, (e) => {
        if (e.touches.length !== 1) {
          return
        }
        e.preventDefault();

        let touch = e.touches[0];
        if (!touch) {
          return
        }
        let simMouseEvent = new MouseEvent(touchToMouse[touchEvent], {
          clientX: touch.clientX,
          clientY: touch.clientY,
        });
        
        canvasObj.dispatchEvent(simMouseEvent);

      }, false)
    }

后记

画板小程序

https://diamondmofeng.github.io/MiniDraw/


I am a noob