surface上的手勢事件


surface上的手勢事件


1、surface上的觸控事件測試。

  • 手指觸控在CHROME和FIREFOX下會觸發touch事件,而IE10是不支持touch事件的。
  • 手指觸控在三個瀏覽器下均會觸發全部的mouse事件。
  • 觸控筆在三個瀏覽器下均會觸發mouse事件。
  • 觸控筆的觸控不能觸發CHROME和FIREFOX下的touch事件。

2、通過touch事件來判斷一個雙指手勢:pinch。

依賴touch事件就可以封裝各種高級的手勢,包括單指和多指的手勢在ios,android移動設備上已有很多的應用了。

touch事件觸發過程:
  • 第一根手指按下:touchstart
  • 第二根手指按下:touchstart
  • ……
  • 滑動手指:touchmove
  • 第一根手指抬起:touchend
  • 第二根手指抬起的時候:touchend,此時event.touches.length == 0

捕獲pinch事件demo: http://beyeah.sinaapp.com/line/pinch.html

(此圖片來自互聯網)

經過測試的瀏覽器有:

  • IOS上的safari和chrome[v28.0.1500],
  • Android上的chrome,
  • surface上的chrome[v28.0.1500]和firefox[v23.0.1](surface上的safari不支持touch事件,不在此次測試范圍) 均能正確的通過touch事件捕獲pinch手勢。

監聽touch事件:

 //touchStart 記錄的是最后一根手指落下時的狀態
 function touchstart(e){
      var touches = e.touches;
           fingers = touches.length;
      touchStart = getTouches(touches,fingers);
 }
 //滑動過程中 任何時候的觸摸狀態curentTouch與初始狀態進行比較
 function touchmove(e){
      var touches = e.touches;
      if(touches.length == fingers){
           curentTouch = getTouches(touches,fingers);
           if(fingers == 2){
                //通過起始和結束的雙指距離來判斷
                var c_distance = parseInt(distance(curentTouch),10);
                var s_distance = parseInt(distance(touchStart),10);
                var diff = s_distance - c_distance;
                Gesture.pinch_diff = diff;
                if(Math.abs(diff) > 10){
                     //連續觸發touchmove :pinching

                }
           }
      }else{...}
 }
 //雙指動作抬起則會觸發兩次touchend事件
 function touchend(e){
      if(fingers == 2){
           if(Math.abs(Gesture.pinch_diff) > 10){
                var type;
                if(Gesture.pinch_diff > 0){
                     type = 'pinchIn';
                }else{
                     type = 'pinchOut';
                }
                alert(type)
                //成功捕獲后清除手勢記錄
           }
      }
 }

3、IE10上的觸摸事件以及捕獲pinch事件IE10實現

IE10(僅IE10)有為觸控筆和手指觸摸特別准備pointer(指針)事件監聽。原本在支持touch事件的移動設備瀏覽器上運行的交互經過較少的修改就可以應用到surface的CHROME、FOREFOX上,IE10則要花一些時間進行兼容了。

 if (window.navigator.msPointerEnabled) {
        // 支持指針事件
 }
 if(navigator.msMaxTouchPoints && navigator.msMaxTouchPoints > 1) {
      //判斷支持多點觸控
      //console.log(navigator.msMaxTouchPoints)
 }
Pointer事件:

MSPointer[Over|Hover|Down|Move|Up|Out]

Pointer事件出發過程:

  • down:第一根手指down->第二根手指down->
  • move: 第一根手指move->第二根手指move->
  • end: 第一根手指up->第二根手指up->

每一次event都包含當前手指的觸摸信息,相比touch事件,Pointer事件提供的接口參數更接近於mouse事件。

捕獲pinch事件demo: http://beyeah.sinaapp.com/line/pinch.html

//pointer事件與touch事件數據格式區別較大,故另寫方法處理監聽
function pointerDown(e){
      var pointerId = e.pointerId;
      var x = e.offsetX;
      var y = e.offsetY;
      //保持事件狀態記錄的數據格式一致,以便判斷
      !pointerStart[pointerId] && (pointerStart[pointerId] = {
           'x' : x,
           'y' : y
      });
 }
 function pointerMove(e){
      var pointerId = e.pointerId;
      var x = e.offsetX;
      var y = e.offsetY;
      curentPointer[pointerId] = {
           'x' : x,
           'y' : y
      }
      _pointerStart = [];
      _curentPointer = [];
      for(var i in pointerStart){
           _pointerStart.push(pointerStart[i]);
           _curentPointer.push(curentPointer[i]);
      }
      //同touch事件判斷pinch手勢的條件一致
      if(_curentPointer.length == 2){
           var c_distance = parseInt(distance(_curentPointer),10);
           var s_distance = parseInt(distance(_pointerStart),10);
           var diff = s_distance - c_distance;
           POINTER.pinch_diff = diff;
           if(Math.abs(diff) > 10){
                //pinching

           }
      }
 }

至此:兼容surface IE10的捕獲pinch手勢方法完成。

tips:
  • a、在surface上,長按默認會觸發系統右鍵菜單,在長按行為另有它用的節點上可以這樣來禁用掉:

    element.addEventListener("MSHoldVisual", function(e) { e.preventDefault(); }, false); element.addEventListener("contextmenu", function(e) { e.preventDefault(); }, false);

  • b、IE10使用一個css屬性:-ms-touch-action: none; 可以防止默認的縮放。

  • c、移動設備safari瀏覽器上阻止默認雙指縮放

    <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no">

4、IE10的MSGesture對象以及觸控筆事件

MSPointer[Over|Hover|Down|Move|Up|Out] ,
  • 觸控筆會觸發此事件 : over ->hover ->down->move->up-<hover->out
  • 手指觸控會觸發:over->down->move->up->out
  • 觸控筆除了可以比手指更精准的替代鼠標操作外,專門針對觸控筆的IE10應用可能會陸續出現。
微軟還提供了一個MSGesture對象來支持較高級別的筆勢(如按、平移、點擊)而無需自己捕獲每個指針事件。

通過MSGesture對象來判斷滑動:

//實例化一個手勢對象
var gesture = new MSGesture();
var elm = document.body;
gesture.target = elm;
//手勢對象在手勢識別期間處理哪些指針
 elm.addEventListener("MSPointerDown", function (evt) {
      gesture.addPointer(evt.pointerId);
 });

//判斷手勢狀態的三個事件:MSGestureStart、MSGestureChange(隨着手勢的持續重復觸發)和 MSGestureEnd
//MSgesture對象返回的每個事件都包含縮放(收縮)、旋轉、轉換和速度等相關信息。
//通過連續觸發的MSGestureChange事件的速度信息簡單的判定一個動態手勢

 function handlegesture(e){
    //通過滑動速度判斷swipe  
      if(e.velocityX>1.5){
           alert('swipright');
      }
      if(e.velocityX<-1.5){
           alert('swipleft');
      }
      //直接通過scale信息判斷pinch
      if(e.scale > 1){
        alert('pinchout')
      }else if(e.scale < 1){
        alert('pinchin')
      }
 }
//輕擊,長按等靜態手勢,則可直接判定:
//MSGestureHold,MSGestureTap
function handlegesturetap(){
      alert('tap')
 }
 //監聽事件
elm.addEventListener("MSGestureChange", handlegesture);
elm.addEventListener("MSGestureTap", handlegesturetap);

demo: http://beyeah.sinaapp.com/line/pointer.html

5、小結

  1. 目前通過UA信息無法區分是支持觸摸的surface還是普通的PC。可以通過['createTouch' in document]來判斷是否支持touch事件。JQuery Mobile封裝的tap,swipe等基礎的單指手勢事件在surface上得到較好的支持。但surface並未被識別為支持觸摸的Mobile設備,得到支持是因為JQuery Mobile向mouse事件的兼容。
  2. 如果應用面向全部的移動設備的話,比起使用MSGesture對象提供事件信息,在原touch事件上監聽pointer事件向surface-IE10作兼容可能具有更好的擴展性。
  3. 現有的web網頁針對surface和大屏的ipad等pad設備在兼容mouse事件的基礎上加一些手勢交互能較好的提升用戶體驗。
  4. demo會繼續更新並添加更多手勢判定
參考文檔:
  • http://msdn.microsoft.com/zh-cn/library/ie/hh968249(v=vs.85).aspx
  • http://www.w3.org/TR/touch-events/
  • JQuery Mobile:http://api.jquerymobile.com/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM