render.js 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. const MIN_DISTANCE = 10;
  2. export default {
  3. showWatch(newVal, oldVal, ownerInstance, instance,self) {
  4. let state = self.state
  5. this.getDom(instance, ownerInstance,self)
  6. if (newVal && newVal !== 'none') {
  7. this.openState(newVal, instance, ownerInstance,self)
  8. return
  9. }
  10. if (state.left) {
  11. this.openState('none', instance, ownerInstance,self)
  12. }
  13. this.resetTouchStatus(instance,self)
  14. },
  15. /**
  16. * 开始触摸操作
  17. * @param {Object} e
  18. * @param {Object} ins
  19. */
  20. touchstart(e, ownerInstance, self) {
  21. let instance = e.instance;
  22. let disabled = instance.getDataset().disabled
  23. let state = self.state;
  24. this.getDom(instance, ownerInstance, self)
  25. // fix by mehaotian, TODO 兼容 app-vue 获取dataset为字符串 , h5 获取 为 undefined 的问题,待框架修复
  26. disabled = this.getDisabledType(disabled)
  27. if (disabled) return
  28. // 开始触摸时移除动画类
  29. instance.requestAnimationFrame(function() {
  30. instance.removeClass('ani');
  31. ownerInstance.callMethod('closeSwipe');
  32. })
  33. // 记录上次的位置
  34. state.x = state.left || 0
  35. // 计算滑动开始位置
  36. this.stopTouchStart(e, ownerInstance, self)
  37. },
  38. /**
  39. * 开始滑动操作
  40. * @param {Object} e
  41. * @param {Object} ownerInstance
  42. */
  43. touchmove(e, ownerInstance, self) {
  44. let instance = e.instance;
  45. let disabled = instance.getDataset().disabled
  46. let state = self.state
  47. // fix by mehaotian, TODO 兼容 app-vue 获取dataset为字符串 , h5 获取 为 undefined 的问题,待框架修复
  48. disabled = this.getDisabledType(disabled)
  49. if (disabled) return
  50. // 是否可以滑动页面
  51. this.stopTouchMove(e, self);
  52. if (state.direction !== 'horizontal') {
  53. return;
  54. }
  55. if (e.preventDefault) {
  56. // 阻止页面滚动
  57. e.preventDefault()
  58. }
  59. let x = state.x + state.deltaX
  60. this.move(x, instance, ownerInstance, self)
  61. },
  62. /**
  63. * 结束触摸操作
  64. * @param {Object} e
  65. * @param {Object} ownerInstance
  66. */
  67. touchend(e, ownerInstance, self) {
  68. let instance = e.instance;
  69. let disabled = instance.getDataset().disabled
  70. let state = self.state
  71. // fix by mehaotian, TODO 兼容 app-vue 获取dataset为字符串 , h5 获取 为 undefined 的问题,待框架修复
  72. disabled = this.getDisabledType(disabled)
  73. if (disabled) return
  74. // 滑动过程中触摸结束,通过阙值判断是开启还是关闭
  75. // fixed by mehaotian 定时器解决点击按钮,touchend 触发比 click 事件时机早的问题 ,主要是 ios13
  76. this.moveDirection(state.left, instance, ownerInstance, self)
  77. },
  78. /**
  79. * 设置移动距离
  80. * @param {Object} value
  81. * @param {Object} instance
  82. * @param {Object} ownerInstance
  83. */
  84. move(value, instance, ownerInstance, self) {
  85. value = value || 0
  86. let state = self.state
  87. let leftWidth = state.leftWidth
  88. let rightWidth = state.rightWidth
  89. // 获取可滑动范围
  90. state.left = this.range(value, -rightWidth, leftWidth);
  91. instance.requestAnimationFrame(function() {
  92. instance.setStyle({
  93. transform: 'translateX(' + state.left + 'px)',
  94. '-webkit-transform': 'translateX(' + state.left + 'px)'
  95. })
  96. })
  97. },
  98. /**
  99. * 获取元素信息
  100. * @param {Object} instance
  101. * @param {Object} ownerInstance
  102. */
  103. getDom(instance, ownerInstance, self) {
  104. let state = self.state
  105. var leftDom = ownerInstance.$el.querySelector('.button-group--left')
  106. var rightDom = ownerInstance.$el.querySelector('.button-group--right')
  107. state.leftWidth = leftDom.offsetWidth || 0
  108. state.rightWidth = rightDom.offsetWidth || 0
  109. state.threshold = instance.getDataset().threshold
  110. },
  111. getDisabledType(value) {
  112. return (typeof(value) === 'string' ? JSON.parse(value) : value) || false;
  113. },
  114. /**
  115. * 获取范围
  116. * @param {Object} num
  117. * @param {Object} min
  118. * @param {Object} max
  119. */
  120. range(num, min, max) {
  121. return Math.min(Math.max(num, min), max);
  122. },
  123. /**
  124. * 移动方向判断
  125. * @param {Object} left
  126. * @param {Object} value
  127. * @param {Object} ownerInstance
  128. * @param {Object} ins
  129. */
  130. moveDirection(left, ins, ownerInstance, self) {
  131. var state = self.state
  132. var threshold = state.threshold
  133. var position = state.position
  134. var isopen = state.isopen || 'none'
  135. var leftWidth = state.leftWidth
  136. var rightWidth = state.rightWidth
  137. if (state.deltaX === 0) {
  138. this.openState('none', ins, ownerInstance, self)
  139. return
  140. }
  141. if ((isopen === 'none' && rightWidth > 0 && -left > threshold) || (isopen !== 'none' && rightWidth > 0 &&
  142. rightWidth +
  143. left < threshold)) {
  144. // right
  145. this.openState('right', ins, ownerInstance, self)
  146. } else if ((isopen === 'none' && leftWidth > 0 && left > threshold) || (isopen !== 'none' && leftWidth > 0 &&
  147. leftWidth - left < threshold)) {
  148. // left
  149. this.openState('left', ins, ownerInstance, self)
  150. } else {
  151. // default
  152. this.openState('none', ins, ownerInstance, self)
  153. }
  154. },
  155. /**
  156. * 开启状态
  157. * @param {Boolean} type
  158. * @param {Object} ins
  159. * @param {Object} ownerInstance
  160. */
  161. openState(type, ins, ownerInstance, self) {
  162. let state = self.state
  163. let leftWidth = state.leftWidth
  164. let rightWidth = state.rightWidth
  165. let left = ''
  166. state.isopen = state.isopen ? state.isopen : 'none'
  167. switch (type) {
  168. case "left":
  169. left = leftWidth
  170. break
  171. case "right":
  172. left = -rightWidth
  173. break
  174. default:
  175. left = 0
  176. }
  177. // && !state.throttle
  178. if (state.isopen !== type) {
  179. state.throttle = true
  180. ownerInstance.callMethod('change', {
  181. open: type
  182. })
  183. }
  184. state.isopen = type
  185. // 添加动画类
  186. ins.requestAnimationFrame(()=> {
  187. ins.addClass('ani');
  188. this.move(left, ins, ownerInstance, self)
  189. })
  190. },
  191. getDirection(x, y) {
  192. if (x > y && x > MIN_DISTANCE) {
  193. return 'horizontal';
  194. }
  195. if (y > x && y > MIN_DISTANCE) {
  196. return 'vertical';
  197. }
  198. return '';
  199. },
  200. /**
  201. * 重置滑动状态
  202. * @param {Object} event
  203. */
  204. resetTouchStatus(instance, self) {
  205. let state = self.state;
  206. state.direction = '';
  207. state.deltaX = 0;
  208. state.deltaY = 0;
  209. state.offsetX = 0;
  210. state.offsetY = 0;
  211. },
  212. /**
  213. * 设置滑动开始位置
  214. * @param {Object} event
  215. */
  216. stopTouchStart(event, ownerInstance, self) {
  217. let instance = event.instance;
  218. let state = self.state
  219. this.resetTouchStatus(instance, self);
  220. var touch = event.touches[0];
  221. state.startX = touch.clientX;
  222. state.startY = touch.clientY;
  223. },
  224. /**
  225. * 滑动中,是否禁止打开
  226. * @param {Object} event
  227. */
  228. stopTouchMove(event, self) {
  229. let instance = event.instance;
  230. let state = self.state;
  231. let touch = event.touches[0];
  232. state.deltaX = touch.clientX - state.startX;
  233. state.deltaY = touch.clientY - state.startY;
  234. state.offsetY = Math.abs(state.deltaY);
  235. state.offsetX = Math.abs(state.deltaX);
  236. state.direction = state.direction || this.getDirection(state.offsetX, state.offsetY);
  237. }
  238. }