touch-simulator.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /**
  2. * 模拟移动端 touch 事件
  3. */
  4. var eventTarget;
  5. // polyfills
  6. if (!document.createTouch) {
  7. document.createTouch = function(view, target, identifier, pageX, pageY, screenX, screenY) {
  8. // auto set
  9. return new Touch(target, identifier, {
  10. pageX: pageX,
  11. pageY: pageY,
  12. screenX: screenX,
  13. screenY: screenY,
  14. clientX: pageX - window.pageXOffset,
  15. clientY: pageY - window.pageYOffset
  16. }, 0, 0);
  17. };
  18. }
  19. if (!document.createTouchList) {
  20. document.createTouchList = function() {
  21. var touchList = TouchList();
  22. for (var i = 0; i < arguments.length; i++) {
  23. touchList[i] = arguments[i];
  24. }
  25. touchList.length = arguments.length;
  26. return touchList;
  27. };
  28. }
  29. /**
  30. * create an touch point
  31. * @constructor
  32. * @param target
  33. * @param identifier
  34. * @param pos
  35. * @param deltaX
  36. * @param deltaY
  37. * @returns {Object} touchPoint
  38. */
  39. var Touch = function Touch(target, identifier, pos, deltaX, deltaY) {
  40. deltaX = deltaX || 0;
  41. deltaY = deltaY || 0;
  42. this.identifier = identifier;
  43. this.target = target;
  44. this.clientX = pos.clientX + deltaX;
  45. this.clientY = pos.clientY + deltaY;
  46. this.screenX = pos.screenX + deltaX;
  47. this.screenY = pos.screenY + deltaY;
  48. this.pageX = pos.pageX + deltaX;
  49. this.pageY = pos.pageY + deltaY;
  50. };
  51. /**
  52. * create empty touchlist with the methods
  53. * @constructor
  54. * @returns touchList
  55. */
  56. function TouchList() {
  57. var touchList = [];
  58. touchList['item'] = function(index) {
  59. return this[index] || null;
  60. };
  61. // specified by Mozilla
  62. touchList['identifiedTouch'] = function(id) {
  63. return this[id + 1] || null;
  64. };
  65. return touchList;
  66. }
  67. /**
  68. * Simple trick to fake touch event support
  69. * this is enough for most libraries like Modernizr and Hammer
  70. */
  71. function fakeTouchSupport() {
  72. var objs = [window, document.documentElement];
  73. var props = ['ontouchstart', 'ontouchmove', 'ontouchcancel', 'ontouchend'];
  74. for (var o = 0; o < objs.length; o++) {
  75. for (var p = 0; p < props.length; p++) {
  76. if (objs[o] && objs[o][props[p]] === undefined) {
  77. objs[o][props[p]] = null;
  78. }
  79. }
  80. }
  81. }
  82. /**
  83. * only trigger touches when the left mousebutton has been pressed
  84. * @param touchType
  85. * @returns {Function}
  86. */
  87. function onMouse(touchType) {
  88. return function(ev) {
  89. // prevent mouse events
  90. if (ev.which !== 1) {
  91. return;
  92. }
  93. // The EventTarget on which the touch point started when it was first placed on the surface,
  94. // even if the touch point has since moved outside the interactive area of that element.
  95. // also, when the target doesnt exist anymore, we update it
  96. if (ev.type === 'mousedown' || !eventTarget || eventTarget && !eventTarget.dispatchEvent) {
  97. eventTarget = ev.target;
  98. }
  99. triggerTouch(touchType, ev);
  100. // reset
  101. if (ev.type === 'mouseup') {
  102. eventTarget = null;
  103. }
  104. };
  105. }
  106. /**
  107. * trigger a touch event
  108. * @param eventName
  109. * @param mouseEv
  110. */
  111. function triggerTouch(eventName, mouseEv) {
  112. var touchEvent = document.createEvent('Event');
  113. touchEvent.initEvent(eventName, true, true);
  114. touchEvent.altKey = mouseEv.altKey;
  115. touchEvent.ctrlKey = mouseEv.ctrlKey;
  116. touchEvent.metaKey = mouseEv.metaKey;
  117. touchEvent.shiftKey = mouseEv.shiftKey;
  118. touchEvent.touches = getActiveTouches(mouseEv);
  119. touchEvent.targetTouches = getActiveTouches(mouseEv);
  120. touchEvent.changedTouches = createTouchList(mouseEv);
  121. eventTarget.dispatchEvent(touchEvent);
  122. }
  123. /**
  124. * create a touchList based on the mouse event
  125. * @param mouseEv
  126. * @returns {TouchList}
  127. */
  128. function createTouchList(mouseEv) {
  129. var touchList = TouchList();
  130. touchList.push(new Touch(eventTarget, 1, mouseEv, 0, 0));
  131. return touchList;
  132. }
  133. /**
  134. * receive all active touches
  135. * @param mouseEv
  136. * @returns {TouchList}
  137. */
  138. function getActiveTouches(mouseEv) {
  139. // empty list
  140. if (mouseEv.type === 'mouseup') {
  141. return TouchList();
  142. }
  143. return createTouchList(mouseEv);
  144. }
  145. /**
  146. * TouchEmulator initializer
  147. */
  148. function TouchEmulator() {
  149. fakeTouchSupport();
  150. window.addEventListener('mousedown', onMouse('touchstart'), true);
  151. window.addEventListener('mousemove', onMouse('touchmove'), true);
  152. window.addEventListener('mouseup', onMouse('touchend'), true);
  153. }
  154. // start distance when entering the multitouch mode
  155. TouchEmulator['multiTouchOffset'] = 75;
  156. new TouchEmulator();