index.wxs 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. var MIN_DISTANCE = 10;
  2. /**
  3. * 判断当前是否为H5、app-vue
  4. */
  5. var IS_HTML5 = false
  6. if (typeof window === 'object') IS_HTML5 = true
  7. /**
  8. * 监听页面内值的变化,主要用于动态开关swipe-action
  9. * @param {Object} newValue
  10. * @param {Object} oldValue
  11. * @param {Object} ownerInstance
  12. * @param {Object} instance
  13. */
  14. function sizeReady(newValue, oldValue, ownerInstance, instance) {
  15. var state = instance.getState()
  16. var buttonPositions = JSON.parse(newValue)
  17. if (!buttonPositions || !buttonPositions.data || buttonPositions.data.length === 0) return
  18. state.leftWidth = buttonPositions.data[0].width
  19. state.rightWidth = buttonPositions.data[1].width
  20. state.threshold = instance.getDataset().threshold
  21. if (buttonPositions.show && buttonPositions.show !== 'none') {
  22. openState(buttonPositions.show, instance, ownerInstance)
  23. return
  24. }
  25. if (state.left) {
  26. openState('none', instance, ownerInstance)
  27. }
  28. resetTouchStatus(instance)
  29. }
  30. /**
  31. * 开始触摸操作
  32. * @param {Object} e
  33. * @param {Object} ins
  34. */
  35. function touchstart(e, ins) {
  36. var instance = e.instance;
  37. var disabled = instance.getDataset().disabled
  38. var state = instance.getState();
  39. // fix by mehaotian, TODO 兼容 app-vue 获取dataset为字符串 , h5 获取 为 undefined 的问题,待框架修复
  40. disabled = (typeof(disabled) === 'string' ? JSON.parse(disabled) : disabled) || false;
  41. if (disabled) return
  42. // 开始触摸时移除动画类
  43. instance.requestAnimationFrame(function() {
  44. instance.removeClass('ani');
  45. ins.callMethod('closeSwipe');
  46. })
  47. // 记录上次的位置
  48. state.x = state.left || 0
  49. // 计算滑动开始位置
  50. stopTouchStart(e, ins)
  51. }
  52. /**
  53. * 开始滑动操作
  54. * @param {Object} e
  55. * @param {Object} ownerInstance
  56. */
  57. function touchmove(e, ownerInstance) {
  58. var instance = e.instance;
  59. var disabled = instance.getDataset().disabled
  60. var state = instance.getState()
  61. // fix by mehaotian, TODO 兼容 app-vue 获取dataset为字符串 , h5 获取 为 undefined 的问题,待框架修复
  62. disabled = (typeof(disabled) === 'string' ? JSON.parse(disabled) : disabled) || false;
  63. if (disabled) return
  64. // 是否可以滑动页面
  65. stopTouchMove(e);
  66. if (state.direction !== 'horizontal') {
  67. return;
  68. }
  69. if (e.preventDefault) {
  70. // 阻止页面滚动
  71. e.preventDefault()
  72. }
  73. move(state.x + state.deltaX, instance, ownerInstance)
  74. }
  75. /**
  76. * 结束触摸操作
  77. * @param {Object} e
  78. * @param {Object} ownerInstance
  79. */
  80. function touchend(e, ownerInstance) {
  81. var instance = e.instance;
  82. var disabled = instance.getDataset().disabled
  83. var state = instance.getState()
  84. // fix by mehaotian, TODO 兼容 app-vue 获取dataset为字符串 , h5 获取 为 undefined 的问题,待框架修复
  85. disabled = (typeof(disabled) === 'string' ? JSON.parse(disabled) : disabled) || false;
  86. if (disabled) return
  87. // 滑动过程中触摸结束,通过阙值判断是开启还是关闭
  88. // fixed by mehaotian 定时器解决点击按钮,touchend 触发比 click 事件时机早的问题 ,主要是 ios13
  89. moveDirection(state.left, instance, ownerInstance)
  90. }
  91. /**
  92. * 设置移动距离
  93. * @param {Object} value
  94. * @param {Object} instance
  95. * @param {Object} ownerInstance
  96. */
  97. function move(value, instance, ownerInstance) {
  98. value = value || 0
  99. var state = instance.getState()
  100. var leftWidth = state.leftWidth
  101. var rightWidth = state.rightWidth
  102. // 获取可滑动范围
  103. state.left = range(value, -rightWidth, leftWidth);
  104. instance.requestAnimationFrame(function() {
  105. instance.setStyle({
  106. transform: 'translateX(' + state.left + 'px)',
  107. '-webkit-transform': 'translateX(' + state.left + 'px)'
  108. })
  109. })
  110. }
  111. /**
  112. * 获取范围
  113. * @param {Object} num
  114. * @param {Object} min
  115. * @param {Object} max
  116. */
  117. function range(num, min, max) {
  118. return Math.min(Math.max(num, min), max);
  119. }
  120. /**
  121. * 移动方向判断
  122. * @param {Object} left
  123. * @param {Object} value
  124. * @param {Object} ownerInstance
  125. * @param {Object} ins
  126. */
  127. function moveDirection(left, ins, ownerInstance) {
  128. var state = ins.getState()
  129. var threshold = state.threshold
  130. var position = state.position
  131. var isopen = state.isopen || 'none'
  132. var leftWidth = state.leftWidth
  133. var rightWidth = state.rightWidth
  134. if (state.deltaX === 0) {
  135. openState('none', ins, ownerInstance)
  136. return
  137. }
  138. if ((isopen === 'none' && rightWidth > 0 && -left > threshold) || (isopen !== 'none' && rightWidth > 0 &&
  139. rightWidth +
  140. left < threshold)) {
  141. // right
  142. openState('right', ins, ownerInstance)
  143. } else if ((isopen === 'none' && leftWidth > 0 && left > threshold) || (isopen !== 'none' && leftWidth > 0 &&
  144. leftWidth - left < threshold)) {
  145. // left
  146. openState('left', ins, ownerInstance)
  147. } else {
  148. // default
  149. openState('none', ins, ownerInstance)
  150. }
  151. }
  152. /**
  153. * 开启状态
  154. * @param {Boolean} type
  155. * @param {Object} ins
  156. * @param {Object} ownerInstance
  157. */
  158. function openState(type, ins, ownerInstance) {
  159. var state = ins.getState()
  160. var position = state.position
  161. var leftWidth = state.leftWidth
  162. var rightWidth = state.rightWidth
  163. var left = ''
  164. state.isopen = state.isopen ? state.isopen : 'none'
  165. switch (type) {
  166. case "left":
  167. left = leftWidth
  168. break
  169. case "right":
  170. left = -rightWidth
  171. break
  172. default:
  173. left = 0
  174. }
  175. // && !state.throttle
  176. if (state.isopen !== type) {
  177. state.throttle = true
  178. ownerInstance.callMethod('change', {
  179. open: type
  180. })
  181. }
  182. state.isopen = type
  183. // 添加动画类
  184. ins.requestAnimationFrame(function() {
  185. ins.addClass('ani');
  186. move(left, ins, ownerInstance)
  187. })
  188. // 设置最终移动位置,理论上只要进入到这个函数,肯定是要打开的
  189. }
  190. function getDirection(x, y) {
  191. if (x > y && x > MIN_DISTANCE) {
  192. return 'horizontal';
  193. }
  194. if (y > x && y > MIN_DISTANCE) {
  195. return 'vertical';
  196. }
  197. return '';
  198. }
  199. /**
  200. * 重置滑动状态
  201. * @param {Object} event
  202. */
  203. function resetTouchStatus(instance) {
  204. var state = instance.getState();
  205. state.direction = '';
  206. state.deltaX = 0;
  207. state.deltaY = 0;
  208. state.offsetX = 0;
  209. state.offsetY = 0;
  210. }
  211. /**
  212. * 设置滑动开始位置
  213. * @param {Object} event
  214. */
  215. function stopTouchStart(event) {
  216. var instance = event.instance;
  217. var state = instance.getState();
  218. resetTouchStatus(instance);
  219. var touch = event.touches[0];
  220. if (IS_HTML5 && isPC()) {
  221. touch = event;
  222. }
  223. state.startX = touch.clientX;
  224. state.startY = touch.clientY;
  225. }
  226. /**
  227. * 滑动中,是否禁止打开
  228. * @param {Object} event
  229. */
  230. function stopTouchMove(event) {
  231. var instance = event.instance;
  232. var state = instance.getState();
  233. var touch = event.touches[0];
  234. if (IS_HTML5 && isPC()) {
  235. touch = event;
  236. }
  237. state.deltaX = touch.clientX - state.startX;
  238. state.deltaY = touch.clientY - state.startY;
  239. state.offsetY = Math.abs(state.deltaY);
  240. state.offsetX = Math.abs(state.deltaX);
  241. state.direction = state.direction || getDirection(state.offsetX, state.offsetY);
  242. }
  243. function isPC() {
  244. var userAgentInfo = navigator.userAgent;
  245. var Agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
  246. var flag = true;
  247. for (var v = 0; v < Agents.length - 1; v++) {
  248. if (userAgentInfo.indexOf(Agents[v]) > 0) {
  249. flag = false;
  250. break;
  251. }
  252. }
  253. return flag;
  254. }
  255. var movable = false
  256. function mousedown(e, ins) {
  257. if (!IS_HTML5) return
  258. if (!isPC()) return
  259. touchstart(e, ins)
  260. movable = true
  261. }
  262. function mousemove(e, ins) {
  263. if (!IS_HTML5) return
  264. if (!isPC()) return
  265. if (!movable) return
  266. touchmove(e, ins)
  267. }
  268. function mouseup(e, ins) {
  269. if (!IS_HTML5) return
  270. if (!isPC()) return
  271. touchend(e, ins)
  272. movable = false
  273. }
  274. function mouseleave(e, ins) {
  275. if (!IS_HTML5) return
  276. if (!isPC()) return
  277. movable = false
  278. }
  279. module.exports = {
  280. sizeReady: sizeReady,
  281. touchstart: touchstart,
  282. touchmove: touchmove,
  283. touchend: touchend,
  284. mousedown: mousedown,
  285. mousemove: mousemove,
  286. mouseup: mouseup,
  287. mouseleave: mouseleave
  288. }