js-Extensions-touchJS

js-Extensions-touchJS是一个非常简单的原生js touch扩展,用于适配移动端的常用touch操作(点击tab、双击dbTab、长按longPress、长按终止longPressCancel、滑动swipe以及具体滑动方向left right up down)

当前为 2022-12-02 提交的版本,查看 最新版本

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

  1. // ==UserScript==
  2. // @name js-Extensions-touchJS
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.5
  5. // @description js-Extensions-touchJS是一个非常简单的原生js touch扩展,用于适配移动端的常用touch操作(点击tab、双击dbTab、长按longPress、长按终止longPressCancel、滑动swipe以及具体滑动方向left right up down)
  6. // @author tutu辣么可爱(greasyfork)/IcedWatermelonJuice(github)
  7. // @grant none
  8. // ==/UserScript==
  9. (function() {
  10. var touchJS = {}
  11.  
  12. function jsonExtend(json1 = {}, json2 = {}, json3 = {}) {
  13. return Object.assign(json1, json2, json3)
  14. }
  15.  
  16. function getFnName(fn) {
  17. if (fn.name) {
  18. return fn.name
  19. } else {
  20. var fnstr = fn.toString().match(/function\s*([^(]*)\(/);
  21. return fnstr ? fnstr[1] : null
  22. }
  23. }
  24. touchJS.bind = function(target, evt, fn, fnName = null) {
  25. if (!target || typeof target !== "object") {
  26. console.error("touchJS.bind(target, evt, fn, fnName)参数错误,对象(target)不存在");
  27. return false;
  28. }
  29. // 预处理
  30. var that = target;
  31. that.libForTouchJsExt = that.libForTouchJsExt ? that.libForTouchJsExt : {};
  32. var fnMap = jsonExtend({}, that.libForTouchJsExt),
  33. fnKeyArray = ["swipe", "left", "right", "up", "down", "tap", "dbTap", "longPress",
  34. "longPressCancel"
  35. ]; //可用的事件名
  36.  
  37. function addFn(e, f, n) {
  38. if (fnKeyArray.indexOf(e) < 0) {
  39. let msg = "touchJS.bind(target, evt, fn, fnName)参数错误,指定事件(evt)不支持。支持的事件列表:";
  40. console.error(msg + fnKeyArray.toString());
  41. return false;
  42. }
  43. fnMap[e] = fnMap[e] ? fnMap[e] : {};
  44. if (!n) { //无方法名,获取并使用默认数字id
  45. defAry = Object.keys(fnMap[e]).filter((v) => {
  46. /^\d{1,}$/.test(v)
  47. });
  48. //获取可用数字id
  49. if (!fnMap[e][defAry.length]) { //假设id连续,长度就是新id
  50. n = defAry.length
  51. } else { //说明id不连续(手动删过事件方法),寻找中间缺少的id
  52. defAry.sort((a, b) => {
  53. return a - b
  54. });
  55. for (let i = 0; i < defAry.length; i++) {
  56. if (defAry[i] !== i) {
  57. n = i;
  58. break;
  59. }
  60. }
  61. }
  62. }
  63. fnMap[e][n] = f
  64. return true
  65. }
  66. if (typeof evt === "string" && typeof fn === "function") {
  67. if (!addFn(evt, fn, fnName ? fnName : getFnName(fn))) {
  68. return false
  69. }
  70. } else if (typeof evt === "object" && !fn) {
  71. for (let e in evt) {
  72. if (!addFn(e, evt[e], getFnName(evt[e]))) {
  73. return false
  74. }
  75. }
  76. }
  77. that.libForTouchJsExt = jsonExtend({}, that.libForTouchJsExt, fnMap);
  78. //添加事件
  79. if (!that.libForTouchJsExt.eventLoaded) {
  80. that.libForTouchJsExt.eventLoaded = true;
  81. var execFn = function(evt,params={}) { //执行方法
  82. if (!evt) {
  83. return false
  84. }
  85. if (/left|right|up|down/.test(evt)) {
  86. evt = [evt, "swipe"];
  87. } else {
  88. evt = [evt];
  89. }
  90. params.target = that;
  91. evt.forEach((e) => {
  92. e = that.libForTouchJsExt[e] ? that.libForTouchJsExt[e] : {};
  93. for (let i in e) {
  94. if (typeof e[i] === "function") {
  95. e[i](params);
  96. }
  97. }
  98. })
  99. }
  100. var lp_timer = -1,
  101. tap_timer = -1,
  102. lp_flag = false,
  103. swipe_flag = false,
  104. tap_sum = 0,
  105. pos = {
  106. x: 0,
  107. y: 0
  108. };
  109. that.addEventListener('touchstart', ts, false);
  110. that.addEventListener('touchmove', tm, false);
  111. that.addEventListener('touchend', te, false);
  112. //具体实现
  113. function dir(past, now) { //判方向
  114. if (Math.abs(past.x - now.x) > Math.abs(past.y - now.y)) {
  115. if (now.x > past.x) {
  116. return "right"
  117. } else {
  118. return "left"
  119. }
  120. } else {
  121. if (now.y > past.y) {
  122. return "down"
  123. } else {
  124. return "up"
  125. }
  126. }
  127. return null
  128. }
  129.  
  130. function ts(e) { //touchstart
  131. e = e || window.event
  132. lp_timer !== -1 && clearTimeout(lp_timer);
  133. lp_timer = -1;
  134. lp_flag = false;
  135. swipe_flag = false;
  136. pos = {
  137. x: e.changedTouches[0].clientX,
  138. y: e.changedTouches[0].clientY
  139. }
  140. lp_timer = setTimeout(function() {
  141. if (!swipe_flag) {
  142. lp_timer = -1;
  143. lp_flag = true;
  144. execFn("longPress", {
  145. 0: pos
  146. });
  147. }
  148. }, 600)
  149. }
  150.  
  151. function tm(e) { //touchmove
  152. var e = e || window.event;
  153. let temp = {
  154. x: e.changedTouches[0].clientX,
  155. y: e.changedTouches[0].clientY
  156. }
  157. if (!lp_flag && (Math.abs(pos.x - temp.x) > 10 || Math.abs(pos.y - temp.y) > 10)) {
  158. swipe_flag = true;
  159. lp_timer !== -1 && clearTimeout(lp_timer);
  160. lp_timer = -1;
  161. execFn(dir(pos, temp), {
  162. 0: pos,
  163. 1: temp
  164. });
  165. }
  166. pos = temp;
  167. }
  168.  
  169. function te(e) { //touchend
  170. var e = e || window.event;
  171. lp_timer !== -1 && clearTimeout(lp_timer);
  172. tap_timer !== -1 && clearTimeout(tap_timer);
  173. lp_timer = -1;
  174. tap_timer = -1;
  175. if (lp_flag) {
  176. execFn("longPressCancel", {
  177. 0: pos
  178. });
  179. } else if (!swipe_flag) {
  180. tap_sum += 1;
  181. if (tap_sum >= 2) {
  182. tap_sum = 0;
  183. execFn("dbTap", {
  184. 0: pos
  185. });
  186. } else {
  187. tap_timer = setTimeout(() => {
  188. tap_sum = 0;
  189. execFn("tap", {
  190. 0: pos
  191. });
  192. }, 200)
  193. }
  194. }
  195. }
  196. }
  197. return that
  198. }
  199. touchJS.unbind = function(target, evt, fnName = null) {
  200. if (!target || typeof target !== "object") {
  201. console.error("touchJS.unbind(target, evt, fnName)参数错误,对象(target)不存在");
  202. return false;
  203. }
  204. var that = target;
  205. if (typeof evt === "string") {
  206. that.libForTouchJsExt = that.libForTouchJsExt ? that.libForTouchJsExt : {};
  207. if (that.libForTouchJsExt[evt]) {
  208. if (fnName) {
  209. fnName = typeof fnName === "function" ? getFnName(fnName) : fnName;
  210. delete that.libForTouchJsExt[evt][fnName];
  211. } else {
  212. delete that.libForTouchJsExt[evt]
  213. }
  214. }
  215. }
  216. return that
  217. }
  218. window.touchJS=touchJS;
  219. })();