Skip to content

Commit

Permalink
Support IE11 touch events, closes madrobby#854 and madrobby#860.
Browse files Browse the repository at this point in the history
IE11 no longer supports older (IE10) "MSPointerEvents", going
with vendor-prefix less "pointerevents" instead.
  • Loading branch information
madrobby committed Nov 25, 2013
1 parent dfe1ada commit 9a5f23e
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 19 deletions.
34 changes: 22 additions & 12 deletions src/touch.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,18 @@
}

function isPrimaryTouch(event){
return event.pointerType == event.MSPOINTER_TYPE_TOUCH && event.isPrimary
return (event.pointerType == 'touch' ||
event.pointerType == event.MSPOINTER_TYPE_TOUCH)
&& event.isPrimary
}

function isPointerEventType(e, type){
return (e.type == 'pointer'+type ||
e.type.toLowerCase() == 'mspointer'+type)
}

$(document).ready(function(){
var now, delta, deltaX = 0, deltaY = 0, firstTouch
var now, delta, deltaX = 0, deltaY = 0, firstTouch, _isPointerType

if ('MSGesture' in window) {
gesture = new MSGesture()
Expand All @@ -56,9 +63,10 @@
touch.el.trigger('swipe'+ swipeDirectionFromVelocity)
}
})
.on('touchstart MSPointerDown', function(e){
if(e.type == 'MSPointerDown' && !isPrimaryTouch(e)) return;
firstTouch = e.type == 'MSPointerDown' ? e : e.touches[0]
.on('touchstart MSPointerDown pointerdown', function(e){
if((_isPointerType = isPointerEventType(e, 'down')) &&
!isPrimaryTouch(e)) return
firstTouch = _isPointerType ? e : e.touches[0]
if (e.touches && e.touches.length === 1 && touch.x2) {
// Clear out touch movement data if we have it sticking around
// This can occur if touchcancel doesn't fire due to preventDefault, etc.
Expand All @@ -76,20 +84,22 @@
touch.last = now
longTapTimeout = setTimeout(longTap, longTapDelay)
// adds the current touch contact for IE gesture recognition
if (gesture && e.type == 'MSPointerDown') gesture.addPointer(e.pointerId);
if (gesture && _isPointerType) gesture.addPointer(e.pointerId);
})
.on('touchmove MSPointerMove', function(e){
if(e.type == 'MSPointerMove' && !isPrimaryTouch(e)) return;
firstTouch = e.type == 'MSPointerMove' ? e : e.touches[0]
.on('touchmove MSPointerMove pointermove', function(e){
if((_isPointerType = isPointerEventType(e, 'move')) &&
!isPrimaryTouch(e)) return
firstTouch = _isPointerType ? e : e.touches[0]
cancelLongTap()
touch.x2 = firstTouch.pageX
touch.y2 = firstTouch.pageY

deltaX += Math.abs(touch.x1 - touch.x2)
deltaY += Math.abs(touch.y1 - touch.y2)
})
.on('touchend MSPointerUp', function(e){
if(e.type == 'MSPointerUp' && !isPrimaryTouch(e)) return;
.on('touchend MSPointerUp pointerup', function(e){
if((_isPointerType = isPointerEventType(e, 'up')) &&
!isPrimaryTouch(e)) return
cancelLongTap()

// swipe
Expand Down Expand Up @@ -141,7 +151,7 @@
// when the browser window loses focus,
// for example when a modal dialog is shown,
// cancel all ongoing events
.on('touchcancel MSPointerCancel', cancelAll)
.on('touchcancel MSPointerCancel pointercancel', cancelAll)

// scrolling the window indicates intention of the user
// to scroll, not tap or swipe, so cancel all ongoing events
Expand Down
31 changes: 24 additions & 7 deletions test/touch.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ <h1>Touch tests</h1>
//
// Zepto's touch module only uses the `pageX/Y` and `target`
// properties of the first touch in the `touches` TouchList
function touchEvent(type, element, x, y) {
function emitTouchEvent(type, element, x, y) {
var event = document.createEvent('Event'),
touch = { pageX: x, pageY: y, target: element }

Expand All @@ -50,10 +50,11 @@ <h1>Touch tests</h1>
element.dispatchEvent(event)
}

// IE 10, Windows Phone 8
// MSPointer events, same idea, different implementation.
// For compatibility accepts the same arguments as `touchEvent`
// (touch event names will be mapped to MSPointer event names)
function MSPointerEvent(type, element, x, y) {
function emitMSPointerEvent(type, element, x, y) {
var event = document.createEvent('Event'),
eventMap = { start: 'Down', move: 'Move', end: 'Up'}

Expand All @@ -67,6 +68,23 @@ <h1>Touch tests</h1>
element.dispatchEvent(event)
}

// IE 11
// Pointer events, same idea again, yet different implementation.
// For compatibility accepts the same arguments as `touchEvent`
// (touch event names will be mapped to pointer event names)
function emitPointerEvent(type, element, x, y) {
var event = document.createEvent('Event'),
eventMap = { start: 'down', move: 'move', end: 'up'}

event.initEvent('pointer'+eventMap[type], true, true)
event.pageX = x
event.pageY = y
event.pointerType = 'touch'
event.isPrimary = true

element.dispatchEvent(event)
}

function down(element, x, y) {
emitEvent('start', element, x, y)
}
Expand All @@ -79,6 +97,7 @@ <h1>Touch tests</h1>

tests = {
setUp: function(){
emitEvent = this.emitEvent
$('<div id=test>TEST ELEMENT</div>').appendTo('body')
},

Expand Down Expand Up @@ -283,11 +302,9 @@ <h1>Touch tests</h1>
// TODO: test swipes in specific directions
}

emitEvent = touchEvent
Evidence('TouchTest', tests)

emitEvent = MSPointerEvent
Evidence('MSPointerTest', tests)
Evidence('TouchTest', $.extend({ emitEvent: emitTouchEvent }, tests))
Evidence('MSPointerTest', $.extend({ emitEvent: emitMSPointerEvent }, tests))
Evidence('PointerTest', $.extend({ emitEvent: emitPointerEvent }, tests))
})()
</script>
</body>
Expand Down

0 comments on commit 9a5f23e

Please sign in to comment.