js-Extensions-touchJS

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

当前为 2022-11-30 提交的版本,查看 最新版本

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

  1. // ==UserScript==
  2. // @name js-Extensions-touchJS
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.4
  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.jsTouchFnMap = that.jsTouchFnMap ? that.jsTouchFnMap : {};
  32. var fnMap = jsonExtend({}, that.jsTouchFnMap),
  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.jsTouchFnMap = jsonExtend({}, that.jsTouchFnMap, fnMap);
  78. //添加事件
  79. if (!that.jsTouchFnMap.eventLoaded) {
  80. that.jsTouchFnMap.eventLoaded = true;
  81. var execFn = function(evt) { //执行方法
  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. evt.forEach((e) => {
  91. e = that.jsTouchFnMap[e] ? that.jsTouchFnMap[e] : {};
  92. for (let i in e) {
  93. if (typeof e[i] === "function") {
  94. e[i]();
  95. }
  96. }
  97. })
  98. }
  99. var lp_timer = -1,
  100. tap_timer = -1,
  101. lp_flag = false,
  102. swipe_flag = false,
  103. tap_sum = 0,
  104. pos = {
  105. x: 0,
  106. y: 0
  107. };
  108. that.addEventListener('touchstart', ts, false);
  109. that.addEventListener('touchmove', tm, false);
  110. that.addEventListener('touchend', te, false);
  111. //具体实现
  112. function dir(past, now) { //判方向
  113. if (Math.abs(past.x - now.x) > Math.abs(past.y - now.y)) {
  114. if (now.x > past.x) {
  115. return "right"
  116. } else {
  117. return "left"
  118. }
  119. } else {
  120. if (now.y > past.y) {
  121. return "down"
  122. } else {
  123. return "up"
  124. }
  125. }
  126. return null
  127. }
  128.  
  129. function ts(e) { //touchstart
  130. e = e || window.event
  131. lp_timer !== -1 && clearTimeout(lp_timer);
  132. lp_timer = -1;
  133. lp_flag = false;
  134. swipe_flag = false;
  135. pos = {
  136. x: e.changedTouches[0].clientX,
  137. y: e.changedTouches[0].clientY
  138. }
  139. lp_timer = setTimeout(function() {
  140. if (!swipe_flag) {
  141. lp_timer = -1;
  142. lp_flag = true;
  143. execFn("longPress")
  144. }
  145. }, 600)
  146. }
  147.  
  148. function tm(e) { //touchmove
  149. var e = e || window.event;
  150. let temp = {
  151. x: e.changedTouches[0].clientX,
  152. y: e.changedTouches[0].clientY
  153. }
  154. if (!lp_flag && (Math.abs(pos.x - temp.x) > 10 || Math.abs(pos.y - temp.y) > 10)) {
  155. swipe_flag = true;
  156. lp_timer !== -1 && clearTimeout(lp_timer);
  157. lp_timer = -1;
  158. execFn(dir(pos, temp));
  159. }
  160. }
  161.  
  162. function te(e) { //touchend
  163. var e = e || window.event;
  164. lp_timer !== -1 && clearTimeout(lp_timer);
  165. tap_timer !== -1 && clearTimeout(tap_timer);
  166. lp_timer = -1;
  167. tap_timer = -1;
  168. if (lp_flag) {
  169. execFn("longPressCancel");
  170. } else if (!swipe_flag) {
  171. tap_sum += 1;
  172. if (tap_sum >= 2) {
  173. tap_sum = 0;
  174. execFn("dbTap");
  175. } else {
  176. tap_timer = setTimeout(() => {
  177. tap_sum = 0;
  178. execFn("tap");
  179. }, 200)
  180. }
  181. }
  182. }
  183. }
  184. return that
  185. }
  186. touchJS.unbind = function(target, evt, fnName = null) {
  187. if (!target || typeof target !== "object") {
  188. console.error("touchJS.unbind(target, evt, fnName)参数错误,对象(target)不存在");
  189. return false;
  190. }
  191. var that = target;
  192. if (typeof evt === "string") {
  193. that.jsTouchFnMap = that.jsTouchFnMap ? that.jsTouchFnMap : {};
  194. if (that.jsTouchFnMap[evt]) {
  195. if (fnName) {
  196. fnName = typeof fnName === "function" ? getFnName(fnName) : fnName;
  197. delete that.jsTouchFnMap[evt][fnName];
  198. } else {
  199. delete that.jsTouchFnMap[evt]
  200. }
  201. }
  202. }
  203. return that
  204. }
  205. window.touchJS=touchJS;
  206. })();