爱简收旧衣按件回收前端代码仓库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

346 lines
7.9 KiB

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