jQuery-Extensions-touchJS

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

目前为 2023-03-02 提交的版本。查看 最新版本

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.cn-greasyfork.org/scripts/454450/1156208/jQuery-Extensions-touchJS.js

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