zepto.touch.js 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. (function($){
  2. var touch = {},
  3. touchTimeout,tapTimeout,swipeTimeout,longTapTimeout,
  4. longTapDelay = 750,
  5. 手势,
  6. 向下,向上,移动,
  7. eventMap,
  8. initialized = false
  9. function swipeDirection(x1,x2,y1,y2){
  10. 返回 数学。abs(x1 - x2)> =
  11. 数学。abs(y1 - y2)?(x1 - x2 > 0 ? '左' : '右'): (y1 - y2 > 0 ? '向上' : '向下')
  12. }
  13. function longTap(){
  14. longTapTimeout = null
  15. 如果(触摸。最后一个){
  16. 触摸。el。触发器(' longTap ')
  17. touch = {}
  18. }
  19. }
  20. function cancelLongTap(){
  21. if(longTapTimeout)clearTimeout(longTapTimeout)
  22. longTapTimeout = null
  23. }
  24. function cancelAll(){
  25. if(touchTimeout)clearTimeout(touchTimeout)
  26. if(tapTimeout)clearTimeout(tapTimeout)
  27. if(swipeTimeout)clearTimeout(swipeTimeout)
  28. if(longTapTimeout)clearTimeout(longTapTimeout)
  29. touchTimeout = tapTimeout = swipeTimeout = longTapTimeout = null
  30. touch = {}
  31. }
  32. function isPrimaryTouch(event){
  33. 返程(事件。pointerType == '触摸' ||
  34. 事件。pointerType == event。MSPOINTER_TYPE_TOUCH)
  35. && 事件。值isPrimary
  36. }
  37. function isPointerEventType(e,type){
  38. return (例如,类型 == '指针' + 类型 ||
  39. e。类型。toLowerCase()== ' mspointer ' + type)
  40. }
  41. //用于测试的辅助函数,因此它们检查不同的API
  42. function unregisterTouchEvents(){
  43. if(! initialized)返回
  44. $(文件)。关闭(eventMap。向下,向下)
  45. 。关(eventMap。起来,向上)
  46. 。off(eventMap。移动,移动)
  47. 。off(eventMap。取消,取消所有)
  48. $(窗口)。off(' scroll ',cancelAll)
  49. cancelAll()
  50. initialized = false
  51. }
  52. 功能 设置(__eventMap){
  53. var now,delta,deltaX = 0,deltaY = 0,firstTouch,_isPointerType
  54. unregisterTouchEvents()
  55. eventMap =(__eventMap &&('向下' 在 __eventMap)) ?__eventMap :
  56. (' ontouchstart ' 的 文件 ?
  57. {
  58. ' down ': ' touchstart ',' up ': ' touchend ',
  59. ' move ': ' touchmove ', '取消': ' touchcancel '
  60. } :
  61. “ onpointerdown ” 的 文件 ?
  62. {
  63. ' down ': ' pointerdown ',' up ': ' pointerup ',
  64. ' move ': ' pointermove ', ' cancel ': ' pointercancel '
  65. } :
  66. “ onmspointerdown ” 的 文件 ?
  67. {
  68. ' down ': ' MSPointerDown ',' up ': ' MSPointerUp ',
  69. ' move ': ' MSPointerMove ', '取消': ' MSPointerCancel '
  70. } : false)
  71. //没有API可用于触摸事件
  72. if(! eventMap)返回
  73. if(' MSGesture ' 在 窗口中){
  74. gesture = new MSGesture()
  75. 手势。target = 文件。身体
  76. $(文件)
  77. 。bind(' MSGestureEnd ',function(e){
  78. var swipeDirectionFromVelocity =
  79. e。velocityX > 1 ? '对' : e。velocityX < - 1 ? '左' : e。速度Y > 1 ? '向下' : e。velocityY < - 1 ? ' Up ' : null
  80. if(swipeDirectionFromVelocity){
  81. 触摸。el。触发('滑动')
  82. 触摸。el。触发器(' swipe ' + swipeDirectionFromVelocity)
  83. }
  84. } )
  85. }
  86. down = function(e){
  87. if((_isPointerType = isPointerEventType(e,' down '))&&
  88. !isPrimaryTouch(e))返回
  89. firstTouch = _isPointerType ?e : e。接触[0]
  90. 如果(Ë。触及 && Ë。触摸。长度 === 1 && 触摸。X2){
  91. //如果我们有触摸移动数据,请清除它们
  92. //如果touchcancel因为preventDefault等而没有触发,就会发生这种情况。
  93. 触摸。x2 = 未定义
  94. 触摸。y2 = 未定义
  95. }
  96. 现在 = 日期。现在()
  97. 三角洲 = 现在 - (触摸。最后 || 现在)
  98. 触摸。EL = $('标签名' 在 firstTouch。目标 ?
  99. firstTouch。target : firstTouch。目标。parentNode)
  100. touchTimeout && clearTimeout(touchTimeout)
  101. 触摸。x1 = firstTouch。pageX属性
  102. 触摸。y1 = firstTouch。pageY
  103. if(delta > 0 && delta <= 250)touch。isDoubleTap = true
  104. 触摸。last = now
  105. longTapTimeout = setTimeout(longTap,longTapDelay)
  106. //为IE手势识别添加当前触摸接触
  107. if(gesture && _isPointerType)手势。addPointer(Ë。pointerId)
  108. }
  109. move = function(e){
  110. if((_isPointerType = isPointerEventType(e,' move '))&&
  111. !isPrimaryTouch(e))返回
  112. firstTouch = _isPointerType ?e : e。接触[0]
  113. cancelLongTap()
  114. 触摸。x2 = firstTouch。pageX属性
  115. 触摸。y2 = firstTouch。pageY
  116. deltaX + = 数学。ABS(触摸。X1 - 触摸。X2)
  117. deltaY + = 数学。ABS(触摸。Y1 - 触摸。Y2)
  118. }
  119. up = function(e){
  120. if((_isPointerType = isPointerEventType(e,' up '))&&
  121. !isPrimaryTouch(e))返回
  122. cancelLongTap()
  123. //轻扫
  124. 如果((触摸。X2 && 数学。ABS(触摸。X1 - 触摸。X2)> 30)||
  125. (触摸。Y2 && 数学。ABS(触摸。Y1 - 触摸。Y2)> 30))
  126. swipeTimeout = setTimeout(function(){
  127. 如果(触摸。EL){
  128. 触摸。el。触发('滑动')
  129. 触摸。el。触发器('滑动' +(swipeDirection(触摸。X1,触摸。X2,触摸。Y1,触摸。Y2)))
  130. }
  131. touch = {}
  132. } ,0)
  133. //正常点击
  134. 否则 ,如果(“最后” 的触摸)
  135. //当delta位置变化超过30像素时,不要点击,
  136. //例如,当移动到一个点并返回原点时
  137. if(deltaX < 30 && deltaY < 30){
  138. //延迟一个刻度线,这样我们可以在'滚动'触发时取消'点击'事件
  139. //('tap'在'scroll'之前触发)
  140. tapTimeout = setTimeout(function(){
  141. //使用cancelTouch()选项触发通用'tap'
  142. //(cancelTouch取消单个与双击的处理,以获得更快的“敲击”响应)
  143. var event = $。活动('点击')
  144. 事件。cancelTouch = cancelAll
  145. // [通过纸张]修复 - >“TypeError:'undefined'不是对象(评估'touch.el.trigger'),双击
  146. 如果(触摸。EL)的触摸。el。触发器(事件)
  147. //立即触发双击
  148. 如果(触摸。isDoubleTap){
  149. 如果(触摸。EL)的触摸。el。触发器(' doubleTap ')
  150. touch = {}
  151. }
  152. //在250ms不活动后触发单击
  153. 其他 {
  154. touchTimeout = setTimeout(function(){
  155. touchTimeout = null
  156. 如果(触摸。EL)的触摸。el。触发器(' singleTap ')
  157. touch = {}
  158. } ,250)
  159. }
  160. } ,0)
  161. } else {
  162. touch = {}
  163. }
  164. deltaX = deltaY = 0
  165. }
  166. $(文件)。上(eventMap。起来,起来)
  167. 。on(eventMap。向下,向下)
  168. 。on(eventMap。移动,移动)
  169. //当浏览器窗口失去焦点时
  170. //例如,当显示模态对话框时,
  171. //取消所有正在进行的活动
  172. $(文件)。on(eventMap。取消,取消所有)
  173. //滚动窗口表示用户的意图
  174. //滚动,不点按或滑动,因此取消所有正在进行的活动
  175. $(窗口)。on(' scroll ',cancelAll)
  176. initialized = true
  177. }
  178. ;[' swipe ',' swipeLeft ',' swipeRight ',' swipeUp ',' swipeDown ',
  179. ' doubleTap ', ' tap ', ' singleTap ', ' longTap ']。forEach( function( eventName){
  180. $。fn[eventName] = function(callback){ return this。on(eventName,callback) }
  181. } )
  182. $。touch = { setup : setup }
  183. $(文件)。准备好(设置)
  184. } )