touch.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. // Zepto.js
  2. // (c) 2010-2012 Thomas Fuchs
  3. // Zepto.js may be freely distributed under the MIT license.
  4. ;(function($){
  5. var touch = {},
  6. touchTimeout, tapTimeout, swipeTimeout,
  7. longTapDelay = 750, longTapTimeout
  8. function parentIfText(node) {
  9. return 'tagName' in node ? node : node.parentNode
  10. }
  11. function swipeDirection(x1, x2, y1, y2) {
  12. var xDelta = Math.abs(x1 - x2), yDelta = Math.abs(y1 - y2)
  13. return xDelta >= yDelta ? (x1 - x2 > 0 ? 'Left' : 'Right') : (y1 - y2 > 0 ? 'Up' : 'Down')
  14. }
  15. function longTap() {
  16. longTapTimeout = null
  17. if (touch.last) {
  18. touch.el.trigger('longTap')
  19. touch = {}
  20. }
  21. }
  22. function cancelLongTap() {
  23. if (longTapTimeout) clearTimeout(longTapTimeout)
  24. longTapTimeout = null
  25. }
  26. function cancelAll() {
  27. if (touchTimeout) clearTimeout(touchTimeout)
  28. if (tapTimeout) clearTimeout(tapTimeout)
  29. if (swipeTimeout) clearTimeout(swipeTimeout)
  30. if (longTapTimeout) clearTimeout(longTapTimeout)
  31. touchTimeout = tapTimeout = swipeTimeout = longTapTimeout = null
  32. touch = {}
  33. }
  34. $(document).ready(function(){
  35. var now, delta
  36. $(document.body)
  37. .bind('touchstart', function(e){
  38. now = Date.now()
  39. delta = now - (touch.last || now)
  40. touch.el = $(parentIfText(e.originalEvent.touches[0].target))
  41. touchTimeout && clearTimeout(touchTimeout)
  42. touch.x1 = e.originalEvent.touches[0].pageX
  43. touch.y1 = e.originalEvent.touches[0].pageY
  44. if (delta > 0 && delta <= 250) touch.isDoubleTap = true
  45. touch.last = now
  46. longTapTimeout = setTimeout(longTap, longTapDelay)
  47. })
  48. .bind('touchmove', function(e){
  49. touch.x2 = e.originalEvent.touches[0].pageX
  50. touch.y2 = e.originalEvent.touches[0].pageY
  51. //触发拉到刷新, TODO 实现下拉刷新
  52. touch.el.trigger('pulltorefresh',[touch.y1,touch.y2]);
  53. if (Math.abs(touch.x1 - touch.x2) > 10)
  54. e.preventDefault()
  55. })
  56. .bind('touchend', function(e){
  57. cancelLongTap()
  58. // swipe
  59. if ((touch.x2 && Math.abs(touch.x1 - touch.x2) > 30) ||
  60. (touch.y2 && Math.abs(touch.y1 - touch.y2) > 30))
  61. swipeTimeout = setTimeout(function() {
  62. touch.el.trigger('swipe')
  63. touch.el.trigger('swipe' + (swipeDirection(touch.x1, touch.x2, touch.y1, touch.y2)))
  64. touch = {}
  65. }, 0)
  66. // normal tap
  67. else if ('last' in touch)
  68. // delay by one tick so we can cancel the 'tap' event if 'scroll' fires
  69. // ('tap' fires before 'scroll')
  70. tapTimeout = setTimeout(function() {
  71. // trigger universal 'tap' with the option to cancelTouch()
  72. // (cancelTouch cancels processing of single vs double taps for faster 'tap' response)
  73. var event = $.Event('tap')
  74. event.cancelTouch = cancelAll
  75. touch.el.trigger(event)
  76. // trigger double tap immediately
  77. if (touch.isDoubleTap) {
  78. touch.el.trigger('doubleTap')
  79. touch = {}
  80. }
  81. // trigger single tap after 250ms of inactivity
  82. else {
  83. touchTimeout = setTimeout(function(){
  84. touchTimeout = null
  85. touch.el.trigger('singleTap')
  86. touch = {}
  87. }, 250)
  88. }
  89. }, 0)
  90. })
  91. .bind('touchcancel', cancelAll)
  92. $(window).bind('scroll', cancelAll)
  93. })
  94. ;['swipe', 'swipeLeft', 'swipeRight', 'swipeUp', 'swipeDown', 'doubleTap', 'tap', 'singleTap', 'longTap'].forEach(function(m){
  95. $.fn[m] = function(callback){ return this.bind(m, callback) }
  96. });
  97. })(jQuery)