touchActionEx

簡単なタッチ操作のイベントを追加します

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.cn-greasyfork.org/scripts/419806/894991/touchActionEx.js

  1. // ==UserScript==
  2. // @name touchActionEx
  3. // @version 0.3
  4. // @description 簡単なタッチ操作のイベントを追加します
  5. // @author y_kahou
  6. // ==/UserScript==
  7. function addTap(ele, {interval = 200} = {}) {
  8. // すでにtapかdoubletapを設定していたら何もしない
  9. if (ele.getAttribute('tap') != null || ele.getAttribute('doubletap') != null)
  10. return
  11. ele.setAttribute('tap','')
  12. ele.addEventListener('touchstart', e => {
  13. if (e.targetTouches.length > 1) {
  14. ele.dataset.tap = 0
  15. return
  16. }
  17. ele.dataset.tap = 1
  18. let to = setTimeout(() => {
  19. ele.dataset.tap = 0
  20. ele.dispatchEvent(new CustomEvent('hold', {detail: {touch: e.targetTouches[0]}}))
  21. }, interval)
  22. ele.dataset.tap_to = to
  23. })
  24. ele.addEventListener('touchmove', e => {
  25. if (ele.dataset.tap == 0)
  26. return
  27. ele.dispatchEvent(new Event('subfocus'))
  28. ele.dataset.tap = 0
  29. clearTimeout(ele.dataset.tap_to)
  30. })
  31. ele.addEventListener('touchend', e => {
  32. if (ele.dataset.tap == 0)
  33. return
  34. ele.dataset.tap = 0
  35. clearTimeout(ele.dataset.tap_to)
  36. ele.dispatchEvent(new CustomEvent('tap', {detail: {touch: e.changedTouches[0]}}))
  37. e.preventDefault()
  38. })
  39. }
  40. function addDoubletap(ele, {interval = 200} = {}) {
  41. // すでにtapかdoubletapを設定していたら何もしない
  42. if (ele.getAttribute('tap') != null || ele.getAttribute('doubletap') != null)
  43. return
  44. ele.setAttribute('doubletap', '')
  45. ele.addEventListener('touchstart', e => {
  46. if (e.targetTouches.length > 1) {
  47. ele.dataset.tap = 0
  48. return
  49. }
  50. ele.dataset.tap = 1
  51. let to = setTimeout(() => {
  52. ele.dataset.tap = 0
  53. ele.dispatchEvent(new CustomEvent('hold', {detail: {touch: e.targetTouches[0]}}))
  54. }, interval)
  55. ele.dataset.tap_to = to
  56. })
  57. ele.addEventListener('touchmove', e => {
  58. if (ele.dataset.tap == 0)
  59. return
  60. ele.dispatchEvent(new Event('subfocus'))
  61. ele.dataset.tap = 0
  62. clearTimeout(ele.dataset.tap_to)
  63. })
  64. ele.addEventListener('touchend', e => {
  65. if (ele.dataset.tap == 0)
  66. return
  67. ele.dataset.tap = 0
  68. clearTimeout(ele.dataset.tap_to)
  69. let event = new CustomEvent('temp', {detail: {touch: e.changedTouches[0]}})
  70. ele.dispatchEvent(event)
  71. e.preventDefault()
  72. })
  73. ele.addEventListener('temp', e => {
  74. if (ele.dataset.dbltap == 1) {
  75. ele.dataset.dbltap = 0
  76. clearTimeout(ele.dataset.dbltap_to)
  77. ele.dispatchEvent(new CustomEvent('doubletap', {detail: e.detail}))
  78. } else {
  79. ele.dataset.dbltap = 1
  80. var to = setTimeout(() => {
  81. ele.dataset.dbltap = 0
  82. ele.dispatchEvent(new CustomEvent('tap', {detail: e.detail}))
  83. }, interval)
  84. ele.dataset.dbltap_to = to
  85. }
  86. })
  87. }
  88. function addSwipe(ele, {min_dist = 50} = {}) {
  89. // すでにswipeかswipe_wayを設定していたら何もしない
  90. if (ele.getAttribute('swipe') != null || ele.getAttribute('swipe_way') != null)
  91. return
  92. ele.setAttribute('swipe','')
  93. ele.addEventListener('touchstart', e => {
  94. if (e.touches.length > 1) {
  95. ele.dataset.start_point = ''
  96. return
  97. }
  98. var x = Math.floor(e.touches[0].screenX)
  99. var y = Math.floor(e.touches[0].screenY)
  100. ele.dataset.start_point = `${x},${y}`
  101. })
  102. ele.addEventListener('touchmove', e => {
  103. if (e.touches.length > 1) {
  104. ele.dataset.start_point = ''
  105. return
  106. }
  107. })
  108. ele.addEventListener('touchend', e => {
  109. if (e.changedTouches.length > 1)
  110. return
  111. var p = ele.dataset.start_point
  112. if (!p)
  113. return
  114. var x1 = Number(p.split(',')[0])
  115. var y1 = Number(p.split(',')[1])
  116. var x2 = Math.floor(e.changedTouches[0].screenX)
  117. var y2 = Math.floor(e.changedTouches[0].screenY)
  118. var ang = Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI
  119. if (ang < 0) ang += 360
  120. var dist = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2))
  121. if (min_dist < dist) {
  122. var dt = {
  123. from: { x: x1, y: y1 },
  124. dest: { x: x2, y: y2 },
  125. angle: ang, distance: dist
  126. }
  127. ele.dispatchEvent(new CustomEvent('swipe', {detail: dt}))
  128. }
  129. })
  130. }
  131. function addSwipeWay(ele, {range = 90, min_dist = 50} = {}) {
  132. // すでにswipe_wayを設定していたら何もしない
  133. if (ele.getAttribute('swipe_way') != null)
  134. return
  135. // swipe未設定なら設定
  136. if (ele.getAttribute('swipe') == null) {
  137. addSwipe(ele, min_dist)
  138. }
  139. ele.removeAttribute('swipe')
  140. ele.setAttribute('swipe_way', '')
  141. ele.addEventListener('swipe', e => {
  142. const ways = ['right', 'down', 'left', 'up']
  143. let ang = e.detail.angle
  144. let dist = e.detail.distance
  145. for (var i in ways) {
  146. var ang_ = (i==0 && 270<ang ? ang-360 : ang)
  147. if (Math.abs(90 * i - ang_) <= range / 2) {
  148. ele.dispatchEvent(new CustomEvent('swipe' + ways[i], { detail: e.detail}))
  149. break
  150. }
  151. }
  152. })
  153. }