render.js 6.7 KB

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