为什么我的智能手机经常“触发”?

时间:2014-02-03 09:22:08

标签: javascript mobile canvas

我想用我的Nexus 4在画布上画线。它在我的电脑上完美运行,但在我的Nexus 4上它会跳过线条。

你可以try it here

我认为问题是touchend事件经常被触发。 为什么会这样?

代码

HTML

<!DOCTYPE html>
<html>
  <head>
    <title>Write Mathematical Formulas</title>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/> <!--320-->
        <style type="text/css">
#myCanvas
{
  border = 1px solid black;
}
#controls
{
  bottom: 0;
  left: 0;
  position: absolute;
  width: 100%;
}
        </style>
  </head>
  <body>
    <div id="container"></div>
    <canvas id = "myCanvas"></canvas>
    <input type="button" style="z-index:2; position:absolute; top:0; left:0" value="Clear" onclick="clearDr()"/>
    <script src="js/recognition.js"></script>
  </body>
</html>

的JavaScript

var canvasWidth = document.documentElement.getElementsByTagName('body')[0].clientWidth - 1;
var canvasHeight = document.documentElement.clientHeight - 25;

var context = document.getElementById('myCanvas').getContext("2d");
var canvas = document.getElementById('myCanvas');
canvas.setAttribute('width', canvasWidth);
canvas.setAttribute('height', canvasHeight);
context = canvas.getContext("2d");

function mouseDownEventHandler(e){
  paint = true;
  if(paint){
    addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop, false);
    redraw();
  }
}

function touchstartEventHandler(e){
  paint = true;
  if(paint){
    addClick(e.touches[0].pageX - this.offsetLeft, e.touches[0].pageY - this.offsetTop, false);
    redraw();
  }
}

function mouseUpEventHandler(e){
  paint = false;
}


function mouseMoveEventHandler(e){
  if(paint){
    addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop, true);
    redraw();
  }
}

function touchMoveEventHandler(e){
  if(paint){
    addClick(e.touches[0].pageX - this.offsetLeft, e.touches[0].pageY - this.offsetTop, true);
    redraw();
  }
}

function addClick(x, y, dragging)
{
  clickX.push(x);
  clickY.push(y);
  clickDrag.push(dragging);
}

function redraw(){
  // Clears the canvas
  context.clearRect(0, 0, context.canvas.width, context.canvas.height); 

  context.strokeStyle = "#df4b26";
  context.lineJoin = "round";
  context.lineWidth = 5;

  for(var i=0; i < clickX.length; i++) {        
    context.beginPath();
    if(clickDrag[i] && i){
      context.moveTo(clickX[i-1], clickY[i-1]);
     }else{
       context.moveTo(clickX[i]-1, clickY[i]);
     }
     context.lineTo(clickX[i], clickY[i]);
     context.closePath();
     context.stroke();
  }
}

function clearDr() {
    context.clearRect(0, 0, context.canvas.width, context.canvas.height); // Clears the canvas
    clickX = new Array();
    clickY = new Array();
    clickDrag = new Array();
}

canvas.addEventListener('mousedown', mouseDownEventHandler);
canvas.addEventListener('touchstart', touchstartEventHandler);

canvas.addEventListener('mousemove',mouseMoveEventHandler);
canvas.addEventListener('touchmove',touchMoveEventHandler);

canvas.addEventListener('mouseup', mouseUpEventHandler);
canvas.addEventListener('touchend', mouseUpEventHandler);

var clickX = new Array();
var clickY = new Array();
var clickDrag = new Array();
var paint;

1 个答案:

答案 0 :(得分:0)

即使使用触摸确保兼容性,大多数(?所有?)浏览器也会模拟鼠标 尝试在触摸事件处理程序上使用stopPropagation和preventDefault来防止两个处理程序都触发。 或者事实上,“干净”的方法是通过开始“比赛”来检测您是否在触摸或鼠标设备上。一旦你知道了设备,只需挂钩相关的处理程序。

function mouseWins(e) { setUpHandler (  true  , e );  }  
function touchWins(e) { setUpHandler (  false , e); }

canvas.addEventListener('mousedown', mouseWins);
canvas.addEventListener('touchstart', touchWins);

function removeRaceHandlers() {
    canvas.removeEventListener('mousedown', mouseWins);
    canvas.removeEventListener('touchstart', touchWins);
}

function setUpHandler(isMouseandNotTouch, detectEvent) {
    removeRaceHandlers();
     if (isMouseandNotTouch) {
        canvas.addEventListener('mouseup', mouseUpEventHandler);
        canvas.addEventListener('mousemove',mouseMoveEventHandler);
        canvas.addEventListener('mousedown', mouseDownEventHandler);
        mouseDownEventHandler (detectEvent)
    } else {
        canvas.addEventListener('touchstart', touchstartEventHandler);
        canvas.addEventListener('touchmove',touchMoveEventHandler);
        canvas.addEventListener('touchend', mouseUpEventHandler);
        touchstartEventHandler (detectEvent)
    }
}

编辑:我添加了第一次检测事件的处理 你可以在你的触摸处理器中阻止默认()/ stopPropagation(),这样我就可以在没有滚动问题的设备上进行测试吗?