技术开发 频道

Web开发:跨浏览器多点触控事件处理

        【IT168 技术】本文主要解释了Web开发者如何通过使用IE10中新引入的pointer事件模型、iOS上的touch事件模型以及W3C标准的扩展鼠标事件模型来编写普适的跨浏览器的触控事件处理代码。

  代码部分

  用鼠标来绘图的基本流程简单明了:

var drawingStarted = false;

  
function DoEvent(eventObject) {

  
if (eventObject.type == "mousedown") {

  drawingStarted
= true;

  startDraw(eventObject.pageX, eventObject.pageY);

  }

  
else if (eventObject.type == "mousemove") {

  
if (drawingStarted) {

  extendDraw(eventObject.pageX, eventObject.pageY);

  }

  }

  
else if (eventObject.type == "mouseup") {

  drawingStarted
= false;

  endDraw();

  }

  }

 

  唯一需要改动以支持IE10的pointer事件的地方就是得注意多点触控可能同时发生(多个点由不同的pointerId区分)。IE10的 pointer模型会触发每个触点的单独的MSPointerDown, MSPointerMove和MSPointerUp事件。

var drawingStarted = {};

  
function DoEvent(eventObject) {

  eventObject.preventManipulation();
// 如果不加上这句, 则屏幕的拖动会代替绘图的动作

  var pointerId
= eventObject.pointerId;

  
if (eventObject.type == "MSPointerDown") {

  drawingStarted[pointerId]
= true;

  startDraw(pointerId, eventObject.pageX, eventObject.pageY);

  }

  
else if (eventObject.type == "MSPointerMove") {

  
if (drawingStarted[pointerId]) {

  extendDraw(pointerId, eventObject.pageX, eventObject.pageY);

  }

  }

  
else if (eventObject.type == "MSPointerUp") {

  delete drawingStarted[pointerId];

  endDraw(pointerId);

  }

  }

 

  要兼容Apple的iOS的touch事件模型则需要你遍历每一个 touchstart, touchmove, 和touchend事件中的changedTouches。因为在iOS事件模型中,同一个事件中可能包含同时产生的不同状态的触控点。像IE10的 pointer模型一样,我们也需要用唯一的id来区分不同的触控点。

  合并以上三种代码需要注意事件名称和触控点id名称的区别,以及鼠标事件模型中并没有触控点id。在以下合并后的代码中,我也加入了对”move”事件是否实际发生的检查。这是因为在IE10的pointer模型中,如果一个触控点始终被压下但没有移 动,即便产生完全相同的x和y坐标,MSPointerMove事件也会被持续触发。通过过滤这些冗余的“移动”,可以消除这些对 extendDraw()的无谓调用。我是这样实现这个检查的:将上一次的start或move事件中的xy坐标存储到一个lastXY的对象中,然后在 后续的事件中检查这个lastXY。lastXY此时代替了前两段示例代码中的drawingStarted对象。

var lastXY = { };
function DoEvent(eventObject) {
    
// 阻止拖动和缩放使得绘图能够正常进行
    
if (eventObject.preventManipulation)
        eventObject.preventManipulation();
    
else
        eventObject.preventDefault();

    
// 如果存在changedTouches数组,则使用它,否则使用eventObject创建一组
    var touchPoints
= (typeof eventObject.changedTouches != 'undefined') ? eventObject.changedTouches : [eventObject];
    for (var i = 0; i < touchPoints.length; ++i) {
        var touchPoint
= touchPoints[i];
        
// 获取唯一的touchPoint id,如果不存在,则使用1作为默认值
        var touchPointId
= (typeof touchPoint.identifier != 'undefined') ? touchPoint.identifier : (typeof touchPoint.pointerId != 'undefined') ? touchPoint.pointerId : 1;

        
if (eventObject.type.match(/(down|start)$/i)) {
            
// 处理mousedown, MSPointerDown,以及touchstart事件
            lastXY[touchPointId]
= { x: touchPoint.pageX, y: touchPoint.pageY };
            startDraw(touchPointId, touchPoint.pageX, touchPoint.pageY);
        }
        
else if (eventObject.type.match(/move$/i)) {
            
// 处理mousemove, MSPointerMove,以及touchmove事件
            
if (lastXY[touchPointId] &#038;& !(lastXY[touchPointId].x == touchPoint.pageX &#038;& lastXY[touchPointId].y == touchPoint.pageY)) {
                lastXY[touchPointId]
= { x: touchPoint.pageX, y: touchPoint.pageY };
                extendDraw(touchPointId, touchPoint.pageX, touchPoint.pageY);
            }
        }
        
else if (eventObject.type.match(/(up|end)$/i)) {
            
// 处理mouseup, MSPointerUp,以及touchend事件
            delete lastXY[touchPointId];
            endDraw(touchPointId);
        }
    }
}

       上面这个例子略去了注册和接受事件以及确保它们被应用在绘图目标上的代码。要使这些代码真正能在所有的浏览器——包括IE9之前的浏览器上跑起来,则还需要一些额外的工作。感兴趣的朋友可以阅读这个跨浏览器的多点触控绘图类的最终代码。
通过同时为鼠标和触控设备编码,web开发者可以确保他们的站点工作在所有的浏览器上——无论是PC,平板还是手机。

 英文原文http://blogs.msdn.com/b/ie/archive/2011/10/19/handling-multi-touch-and-mouse-input-in-all-browsers.aspx

0
相关文章