wx.wxs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  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. leftStyles = leftDom.getBoundingClientRect()
  124. rightStyles = rightDom.getBoundingClientRect()
  125. state.leftWidth = leftStyles.width || 0
  126. state.rightWidth = rightStyles.width || 0
  127. state.threshold = instance.getDataset().threshold
  128. }
  129. /**
  130. * 获取范围
  131. * @param {Object} num
  132. * @param {Object} min
  133. * @param {Object} max
  134. */
  135. function range(num, min, max) {
  136. return Math.min(Math.max(num, min), max);
  137. }
  138. /**
  139. * 移动方向判断
  140. * @param {Object} left
  141. * @param {Object} value
  142. * @param {Object} ownerInstance
  143. * @param {Object} ins
  144. */
  145. function moveDirection(left, ins, ownerInstance) {
  146. var state = ins.getState()
  147. var threshold = state.threshold
  148. var position = state.position
  149. var isopen = state.isopen || 'none'
  150. var leftWidth = state.leftWidth
  151. var rightWidth = state.rightWidth
  152. if (state.deltaX === 0) {
  153. openState('none', ins, ownerInstance)
  154. return
  155. }
  156. if ((isopen === 'none' && rightWidth > 0 && -left > threshold) || (isopen !== 'none' && rightWidth > 0 &&
  157. rightWidth +
  158. left < threshold)) {
  159. // right
  160. openState('right', ins, ownerInstance)
  161. } else if ((isopen === 'none' && leftWidth > 0 && left > threshold) || (isopen !== 'none' && leftWidth > 0 &&
  162. leftWidth - left < threshold)) {
  163. // left
  164. openState('left', ins, ownerInstance)
  165. } else {
  166. // default
  167. openState('none', ins, ownerInstance)
  168. }
  169. }
  170. /**
  171. * 开启状态
  172. * @param {Boolean} type
  173. * @param {Object} ins
  174. * @param {Object} ownerInstance
  175. */
  176. function openState(type, ins, ownerInstance) {
  177. var state = ins.getState()
  178. var leftWidth = state.leftWidth
  179. var rightWidth = state.rightWidth
  180. var left = ''
  181. state.isopen = state.isopen ? state.isopen : 'none'
  182. switch (type) {
  183. case "left":
  184. left = leftWidth
  185. break
  186. case "right":
  187. left = -rightWidth
  188. break
  189. default:
  190. left = 0
  191. }
  192. // && !state.throttle
  193. if (state.isopen !== type) {
  194. state.throttle = true
  195. ownerInstance.callMethod('change', {
  196. open: type
  197. })
  198. }
  199. state.isopen = type
  200. // 添加动画类
  201. ins.requestAnimationFrame(function() {
  202. ins.addClass('ani');
  203. move(left, ins, ownerInstance)
  204. })
  205. // 设置最终移动位置,理论上只要进入到这个函数,肯定是要打开的
  206. }
  207. function getDirection(x, y) {
  208. if (x > y && x > MIN_DISTANCE) {
  209. return 'horizontal';
  210. }
  211. if (y > x && y > MIN_DISTANCE) {
  212. return 'vertical';
  213. }
  214. return '';
  215. }
  216. /**
  217. * 重置滑动状态
  218. * @param {Object} event
  219. */
  220. function resetTouchStatus(instance) {
  221. var state = instance.getState();
  222. state.direction = '';
  223. state.deltaX = 0;
  224. state.deltaY = 0;
  225. state.offsetX = 0;
  226. state.offsetY = 0;
  227. }
  228. /**
  229. * 设置滑动开始位置
  230. * @param {Object} event
  231. */
  232. function stopTouchStart(event) {
  233. var instance = event.instance;
  234. var state = instance.getState();
  235. resetTouchStatus(instance);
  236. var touch = event.touches[0];
  237. if (IS_HTML5 && isPC()) {
  238. touch = event;
  239. }
  240. state.startX = touch.clientX;
  241. state.startY = touch.clientY;
  242. }
  243. /**
  244. * 滑动中,是否禁止打开
  245. * @param {Object} event
  246. */
  247. function stopTouchMove(event) {
  248. var instance = event.instance;
  249. var state = instance.getState();
  250. var touch = event.touches[0];
  251. if (IS_HTML5 && isPC()) {
  252. touch = event;
  253. }
  254. state.deltaX = touch.clientX - state.startX;
  255. state.deltaY = touch.clientY - state.startY;
  256. state.offsetY = Math.abs(state.deltaY);
  257. state.offsetX = Math.abs(state.deltaX);
  258. state.direction = state.direction || getDirection(state.offsetX, state.offsetY);
  259. }
  260. function isPC() {
  261. var userAgentInfo = navigator.userAgent;
  262. var Agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
  263. var flag = true;
  264. for (var v = 0; v < Agents.length - 1; v++) {
  265. if (userAgentInfo.indexOf(Agents[v]) > 0) {
  266. flag = false;
  267. break;
  268. }
  269. }
  270. return flag;
  271. }
  272. var movable = false
  273. function mousedown(e, ins) {
  274. if (!IS_HTML5) return
  275. if (!isPC()) return
  276. touchstart(e, ins)
  277. movable = true
  278. }
  279. function mousemove(e, ins) {
  280. if (!IS_HTML5) return
  281. if (!isPC()) return
  282. if (!movable) return
  283. touchmove(e, ins)
  284. }
  285. function mouseup(e, ins) {
  286. if (!IS_HTML5) return
  287. if (!isPC()) return
  288. touchend(e, ins)
  289. movable = false
  290. }
  291. function mouseleave(e, ins) {
  292. if (!IS_HTML5) return
  293. if (!isPC()) return
  294. movable = false
  295. }
  296. module.exports = {
  297. showWatch: showWatch,
  298. touchstart: touchstart,
  299. touchmove: touchmove,
  300. touchend: touchend,
  301. mousedown: mousedown,
  302. mousemove: mousemove,
  303. mouseup: mouseup,
  304. mouseleave: mouseleave
  305. }