jQuery-Extensions-touchJS

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

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

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

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