tap.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. define("dojox/gesture/tap", [
  2. "dojo/_base/kernel",
  3. "dojo/_base/declare",
  4. "dojo/_base/lang",
  5. "./Base",
  6. "../main"
  7. ], function(kernel, declare, lang, Base, dojox){
  8. // module:
  9. // dojox/gesture/tap
  10. /*=====
  11. dojox.gesture.tap = {
  12. // summary:
  13. // This module provides tap gesture event handlers:
  14. //
  15. // 1. dojox.gesture.tap: 'tap' event
  16. //
  17. // 2. dojox.gesture.tap.hold: 'tap.hold' event
  18. //
  19. // 3. dojox.gesture.tap.doubletap: 'tap.doubletap' event
  20. //
  21. // example:
  22. // A. Used with dojo.connect()
  23. // | dojo.connect(node, dojox.gesture.tap, function(e){});
  24. // | dojo.connect(node, dojox.gesture.tap.hold, function(e){});
  25. // | dojo.connect(node, dojox.gesture.tap.doubletap, function(e){});
  26. //
  27. // B. Used with dojo.on
  28. // | define(['dojo/on', 'dojox/gesture/tap'], function(on, tap){
  29. // | on(node, tap, function(e){});
  30. // | on(node, tap.hold, function(e){});
  31. // | on(node, tap.doubletap, function(e){});
  32. //
  33. // C. Used with dojox.gesture.tap.* directly
  34. // | dojox.gesture.tap(node, function(e){});
  35. // | dojox.gesture.tap.hold(node, function(e){});
  36. // | dojox.gesture.tap.doubletap(node, function(e){});
  37. //
  38. // Though there is always a default gesture instance after being required, e.g
  39. // | require(['dojox/gesture/tap'], function(){...});
  40. //
  41. // It's possible to create a new one with different parameter setting:
  42. // | var myTap = new dojox.gesture.tap.Tap({holdThreshold: 300});
  43. // | dojo.connect(node, myTap, function(e){});
  44. // | dojo.connect(node, myTap.hold, function(e){});
  45. // | dojo.connect(node, myTap.doubletap, function(e){});
  46. };
  47. =====*/
  48. kernel.experimental("dojox.gesture.tap");
  49. // Declare an internal anonymous class which will only be exported
  50. // by module return value e.g. dojox.gesture.tap.Tap
  51. var clz = declare(/*===== "dojox.gesture.tap", =====*/Base, {
  52. // defaultEvent: [readonly] String
  53. // Default event - 'tap'
  54. defaultEvent: "tap",
  55. // subEvents: [readonly] Array
  56. // List of sub events, used by being
  57. // combined with defaultEvent as 'tap.hold', 'tap.doubletap'.
  58. subEvents: ["hold", "doubletap"],
  59. // holdThreshold: Integer
  60. // Threshold(in milliseconds) for 'tap.hold'
  61. holdThreshold: 500,
  62. // holdThreshold: Integer
  63. // Timeout (in milliseconds) for 'tap.doubletap'
  64. doubleTapTimeout: 250,
  65. // tapRadius: Integer
  66. // Valid tap radius from previous touch point
  67. tapRadius: 10,
  68. press: function(/*Object*/data, /*Event*/e){
  69. // summary:
  70. // Overwritten, record initial tap info and register a timeout checker for 'tap.hold'
  71. if(e.touches && e.touches.length >= 2){
  72. //tap gesture is only for single touch
  73. clearTimeout(data.tapTimeOut);
  74. delete data.context;
  75. return;
  76. }
  77. var target = e.target;
  78. this._initTap(data, e);
  79. data.tapTimeOut = setTimeout(lang.hitch(this, function(){
  80. if(this._isTap(data, e)){
  81. this.fire(target, {type: "tap.hold"});
  82. }
  83. delete data.context;
  84. }), this.holdThreshold);
  85. },
  86. release: function(/*Object*/data, /*Event*/e){
  87. // summary:
  88. // Overwritten, fire matched 'tap' or 'tap.doubletap' during touchend
  89. if(!data.context){
  90. clearTimeout(data.tapTimeOut);
  91. return;
  92. }
  93. if(this._isTap(data, e)){
  94. switch(data.context.c){
  95. case 1:
  96. this.fire(e.target, {type: "tap"});
  97. break;
  98. case 2:
  99. this.fire(e.target, {type: "tap.doubletap"});
  100. break;
  101. }
  102. }
  103. clearTimeout(data.tapTimeOut);
  104. },
  105. _initTap: function(/*Object*/data, /*Event*/e){
  106. // summary:
  107. // Update the gesture data with new tap info
  108. if(!data.context){
  109. data.context = {x: 0, y: 0, t: 0, c: 0};
  110. }
  111. var ct = new Date().getTime();
  112. if(ct - data.context.t <= this.doubleTapTimeout){
  113. data.context.c++;
  114. }else{
  115. data.context.c = 1;
  116. data.context.x = e.screenX;
  117. data.context.y = e.screenY;
  118. }
  119. data.context.t = ct;
  120. },
  121. _isTap: function(/*Object*/data, /*Event*/e){
  122. // summary:
  123. // Check whether it's an valid tap
  124. var dx = Math.abs(data.context.x - e.screenX);
  125. var dy = Math.abs(data.context.y - e.screenY);
  126. return dx <= this.tapRadius && dy <= this.tapRadius;
  127. }
  128. });
  129. // the default tap instance for handy use
  130. dojox.gesture.tap = new clz();
  131. // Class for creating a new Tap instance
  132. dojox.gesture.tap.Tap = clz;
  133. return dojox.gesture.tap;
  134. });