Web開發:跨瀏覽器多點觸控事件處理
作者: 51Touch 時間:2011-12-01 源于:MSDN 總點擊:
【導讀】:唯一需要改動以支持IE10的pointer事件的地方就是得注意多點觸控可能同時發生(多個點由不同的pointerId區分)。IE10的 pointer模型會觸發每個觸點的單獨的MSPointerDown, MSPointerMove和MSPointerUp事件。
北京時間12月01日消息,中國觸摸屏網訊,本文主要解釋了Web開發者如何通過使用IE10中新引入的pointer事件模型、iOS上的touch事件模型以及W3C標準的擴展鼠標事件模型來編寫普適的跨瀏覽器的觸控事件處理代碼。
本文來自:http://www.zc28898.cn/touchscreen/news/front/201112/01-12647.html
代碼部分
用鼠標來繪圖的基本流程簡單明了:
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] && !(lastXY[touchPointId].x == touchPoint.pageX && 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之前的瀏覽器上跑起來,則還需要一些額外的工作。感興趣的朋友可以閱讀這個跨瀏覽器的多點觸控繪圖類的最終代碼。
觸摸屏與OLED網推出微信公共平臺,每日一條微信新聞,涵蓋觸摸屏材料、觸摸屏設備、觸控面板行業主要資訊,第一時間了解觸摸屏行業發展動態。關注辦法:微信公眾號“i51touch” 或微信中掃描下面二維碼關注,或這里查看詳細步驟