js-Extensions-touchJS

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

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

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