2013-01-07 19 views
0

我正在嘗試使用Windows.UI.Input.GestureRecognizer類嘗試檢測div上的交叉滑動手勢。元素可滾動時無法檢測到「十字滑動」手勢

當元素處於可滾動區域時,我已經能夠成功實現對此手勢的檢測,但除外。

具體而言,當它是在滾動區域,我的MSPointerDown事件發生後,幾乎立即收到MSPointerCancel事件 - 如果我移動觸摸交互慢慢地,我看到一些MSPointerMove事件,但隨後進入關閉並取消它。

挖掘到WinJS.UI.ListView實現,我幾乎做同樣的事情。該行爲確實工作,所以我不認爲這是與驅動程序或模擬器的問題。

要查看此代碼交叉滑動,改變CSS如下:

.container:更改width: 3000pxwidth: 300px

示例代碼

該代碼可以通過創建一個空的JavaScript應用程序進行測試在Visual Studio中,並將代碼粘貼到下面討論的位置。

的JavaScript,Default.js

WinJS.Namespace.define("Sample", { 
    Swiper: WinJS.Class.define(function (el, options) { 
     this.element = el; 
     WinJS.UI.setOptions(options); 
     this.mouseUp = this.mouseUp.bind(this); 
     this.keyPress = this.keyPress.bind(this); 

     //el.addEventListener("mouseup", this.mouseUp, true); 
     el.addEventListener("keypress", this.keyPress); 

     // Gesture events 
     this.pointerDown = this.pointerDown.bind(this); 
     this.pointerMove = this.pointerMove.bind(this); 
     this.pointerUp = this.pointerUp.bind(this); 
     this.pointerCancel = this.pointerCancel.bind(this); 

     el.addEventListener("MSPointerDown", this.pointerDown, true); 
     el.addEventListener("MSPointerMove", this.pointerMove, true); 
     el.addEventListener("MSPointerUp", this.pointerUp, true); 
     el.addEventListener("MSPointerCancel", this.pointerCancel, true); 
    }, { 
     element: null, 
     _recognizer: null, 
     wasSelected: false, 
     currentTarget: null, 
     pointer: null, 
     mouseUp: function (e) { 
      if(!e) { 
       return; 
      } 

      if(e.button !== Sample.Swiper.RIGHT_MOUSE) { 
       return; 
      } 

      if (!WinJS.Utilities.hasClass(e.srcElement, "swipeable")) { 
       return; 
      } 

      this._toggleSelection(e.srcElement); 
     }, 
     keyPress: function (e) { 
      if (!e) { 
       return; 
      } 

      if (e.keyCode !== WinJS.Utilities.Key.space) { 
       return; 
      } 

      if (!WinJS.Utilities.hasClass(e.srcElement, "swipeable")) { 
       return; 
      } 

      this._toggleSelection(e.srcElement); 
     }, 
     pointerDown: function (e) { 
      console.log("Pointer: Down"); 
      if (!WinJS.Utilities.hasClass(e.srcElement, "swipeable")) { 
       return; 
      } 

      var p = Windows.UI.Input.PointerPoint.getCurrentPoint(e.pointerId); 
      var touch = (e.pointerType === Sample.Swiper.TOUCH); 
      var pointerProperties = p.properties; 
      this.pointer = e.pointerId; 
      if (!touch) { 
       this.mouseUp(e); 
       return; 
      } 

      this.currentTarget = e.srcElement; 
      window.proxy.msSetPointerCapture(p.pointerId); 
      this._getRecognizer().processDownEvent(p); 

      //e.stopImmediatePropagation(); 
      e.preventDefault(); 
     }, 
     pointerMove: function (e) { 
      if (e.pointerId !== this.pointer) { 
       return; 
      } 
      console.log("Pointer: Move"); 
      var ips = Windows.UI.Input.PointerPoint.getIntermediatePoints(e.pointerId); 
      this._getRecognizer().processMoveEvents(ips); 
      //e.stopImmediatePropagation(); 
     }, 
     pointerUp: function (e) { 
      if (e.pointerId !== this.pointer) { 
       return; 
      } 
      console.log("Pointer: Up"); 
      var p = Windows.UI.Input.PointerPoint.getCurrentPoint(e.pointerId); 
      this._getRecognizer().processUpEvent(p); 
      //e.stopImmediatePropagation(); 
     }, 
     pointerCancel: function (e) { 
      if (e.pointerId !== this.pointer) { 
       return; 
      } 

      console.log("Pointer: Canceled"); 
      this._getRecognizer().completeGesture(); 
      e.stopImmediatePropagation(); 
     }, 

     _toggleSelection: function (el) { 
      WinJS.Utilities.toggleClass(el, "selected"); 
     }, 
     _getRecognizer: function() { 
      if (this._recognizer) { 
       return this._recognizer; 
      } 

      var gr = new Windows.UI.Input.GestureRecognizer(); 
      gr.showGestureFeedback = false; 
      var thresholds = gr.crossSlideThresholds; 
      thresholds.selectionStart = WinJS.UI._VERTICAL_SWIPE_SELECTION_THRESHOLD; 
      thresholds.speedBumpStart = WinJS.UI._VERTICAL_SWIPE_SPEED_BUMP_START; 
      thresholds.speedBumpEnd = WinJS.UI._VERTICAL_SWIPE_SPEED_BUMP_END; 
      thresholds.rearrangeStart = null; 

      gr.crossSlideThresholds = thresholds; 
      gr.crossSlideHorizontally = false; 
      var settings = Windows.UI.Input.GestureSettings; 
      gr.gestureSettings = settings.crossSlide; 
      gr.addEventListener("crosssliding", function (e) { 
       var el = this.currentTarget || document.createElement("div"); 
       console.log("CrossSlide State: " + e.crossSlidingState); 
       switch (e.crossSlidingState) { 
        case Windows.UI.Input.CrossSlidingState.selecting: 
         this.wasSelected = true; 
         break; 

        case Windows.UI.Input.CrossSlidingState.completed: 
         if (this.wasSelected) { 
          this._toggleSelection(this.currentTarget); 
         } 
         this.wasSelected = false; 
         this.currentTarget = false; 
         break; 

        default: 
         this.wasSelected = false; 
         break; 
       } 
      }.bind(this)); 
      gr.addEventListener("manipulationstarted", function (e) { 
       debugger; 
      }); 
      this._recognizer = gr; 

      return gr; 
     } 
    }, { 
     RIGHT_MOUSE: 2, 
     TOUCH: 2, 
    }), 
}); 

HTML,在default.html中更換車身

<body> 
    <div class="scroller" data-win-control="Sample.Swiper"> 
     <div id="proxy"></div> 
     <div class="container"> 
      <div class="item swipeable" 
       tabindex="0"> 
      </div> 
     </div> 
    </div> 
</body> 

CSS,添加到default.css

.scroller { 
    width: 100vw; 
    height: 100vh; 
    overflow-x: auto; 
    -ms-touch-action: auto; 
} 
.container { 
    width: 3000px; 
    height: 100vh; 
    display: -ms-grid; 
    -ms-grid-columns: 1fr 100px 1fr; 
    -ms-grid-rows: 1fr 100px 1fr; 
} 

.item { 
    background-color: red; 
    -ms-grid-column: 2; 
    -ms-grid-row: 2; 
} 

.selected { 
    outline-color: white; 
    outline-style: solid; 
    outline-width: 3px; 
} 

回答

1

這是因爲-ms-touch-action需要在特定的平移軸上進行「固定」以進行直接操作。所以,如果你想要一個垂直的十字滑塊(例如滑動手指),那麼你需要確保你想檢測的元素交叉滑動-ms-touch-action設置爲pan-x,以啓用水平移動,但不是垂直移動。滾輪應該有-ms-touch-action設置爲auto

(這會教我看在VS的智能感知,而不是看文件,我知道有一些東西在這裏)