index.wxs 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. /**
  2. * 此为wxs模块,只支持APP-VUE,微信和QQ小程序以及H5平台
  3. * wxs内部不支持es6语法,变量只能使用var定义,无法使用解构,箭头函数等特性
  4. */
  5. // 开始触摸
  6. function touchStart(event, ownerInstance) {
  7. // 触发事件的组件的ComponentDescriptor实例
  8. var instance = event.instance
  9. // wxs内的局部变量快照,此快照是属于整个组件,在touchstart和touchmove事件中都能获取到相同的结果
  10. var state = instance.getState()
  11. if (state.disabled) return
  12. var touches = event.touches
  13. // 如果进行的是多指触控,不允许操作
  14. if (touches && touches.length > 1) return
  15. // 标识当前为滑动中状态
  16. state.moving = true
  17. // 记录触摸开始点的坐标点
  18. state.startX = touches[0].pageX
  19. state.startY = touches[0].pageY
  20. // 记录开始触摸的时间
  21. state.touchStartTime = getDate().getTime()
  22. ownerInstance.callMethod('closeOther')
  23. }
  24. // 触摸滑动
  25. function touchMove(event, ownerInstance) {
  26. // 触发事件的组件的ComponentDescriptor实例
  27. var instance = event.instance
  28. // wxs内的局部变量快照,此快照是属于整个组件,在touchstart和touchmove事件中都能获取到相同的结果
  29. var state = instance.getState()
  30. if (state.disabled || !state.moving) return
  31. var touches = event.touches
  32. var pageX = touches[0].pageX
  33. var pageY = touches[0].pageY
  34. var moveX = pageX - state.startX
  35. var moveY = pageY - state.startY
  36. var buttonsWidth = state.buttonsWidth
  37. // 移动的X轴距离大于Y轴距离,也即终点与起点位置连线,与X轴夹角小于45度时,禁止页面滚动
  38. if (Math.abs(moveX) > Math.abs(moveY) || Math.abs(moveX) > state.threshold) {
  39. // event.preventDefault && event.preventDefault()
  40. // event.stopPropagation && event.stopPropagation()
  41. }
  42. // 移动的Y轴距离大于X轴距离,也即终点与起点位置连线,与Y轴夹角小于45度时,认为页面时上下滑动而不是左右滑动单元格
  43. if (Math.abs(moveX) < Math.abs(moveY)) return
  44. // 限制右滑的距离,不允许内容部分往右偏移,右滑会导致X轴偏移值大于0,以此做判断
  45. // 此处不能直接return,因为滑动过程中会缺失某些关键点坐标,会导致错乱,所以处理的方法是在超出后设置为0
  46. if (state.status === 'open') {
  47. // 在开启状态下,忽略左滑动
  48. if (moveX < 0) moveX = 0
  49. // 要收起菜单,最大能移动的距离为按钮的总宽度
  50. if (moveX > buttonsWidth) moveX = buttonsWidth
  51. // 如果是已经打开的状态,向左滑动时,移动收起菜单
  52. moveSwipeAction(-buttonsWidth + moveX, instance, ownerInstance)
  53. } else {
  54. // 关闭状态下,忽略右滑
  55. if (moveX > 0) return
  56. // 滑动的距离不允许超过所有按钮的总宽度,此时只能左滑
  57. // 滑动距离设置为按钮的宽度(负数)
  58. if (Math.abs(moveX) > buttonsWidth) moveX = -buttonsWidth
  59. // 在滑动过程中不断移动单元格内容,使其不断显示出来
  60. moveSwipeAction(moveX, instance, ownerInstance)
  61. }
  62. }
  63. // 触摸结束
  64. function touchEnd(event, ownerInstance) {
  65. // 触发事件的组件的ComponentDescriptor实例
  66. var instance = event.instance
  67. // wxs内的局部变量快照,此快照是属于整个组件,在touchstart和touchmove事件中都能获取到相同的结果
  68. var state = instance.getState()
  69. if (!state.moving || state.disabled) return
  70. var touches = event.changedTouches ? event.changedTouches[0] : {}
  71. var pageX = touches.pageX
  72. var pageY = touches.pageY
  73. var moveX = pageX - state.startX
  74. if (state.status === 'open') {
  75. // 在开启状态下,忽略左滑动
  76. if (moveX < 0) moveX = 0
  77. // 在开启状态下,点击一下内容区域,moveX为0,也即没有移动,这是执行收起操作
  78. if (moveX === 0) {
  79. return closeSwipeAction(instance, ownerInstance)
  80. }
  81. // 在开启状态下,滑动距离小于阈值,则默认不关闭同时恢复原来的打开状态
  82. if (Math.abs(moveX) < state.threshold) {
  83. openSwipeAction(instance, ownerInstance)
  84. } else {
  85. // 如果滑动距离大于阈值则执行收起逻辑
  86. closeSwipeAction(instance, ownerInstance)
  87. }
  88. } else {
  89. // 获取手指离开的时间
  90. var touchEndTime = getDate().getTime()
  91. // 判断是否点击了
  92. if (Math.abs(pageX - state.startX) < 5 && Math.abs(pageY - state.startY) < 5 && touchEndTime - state.touchStartTime < 100) {
  93. ownerInstance.callMethod('handlerItemClick')
  94. }
  95. // 在关闭状态下,忽略右滑动
  96. if (moveX > 0) return
  97. if (Math.abs(moveX) < state.threshold) {
  98. closeSwipeAction(instance, ownerInstance)
  99. } else {
  100. openSwipeAction(instance, ownerInstance)
  101. }
  102. }
  103. }
  104. // 获取过渡时间
  105. function getDuration(value) {
  106. if (value.toString().indexOf('s') >= 0) return value
  107. return value > 30 ? value + 'ms' : value + 's'
  108. }
  109. // 移动滑动选择器内容区域,同时显示出其隐藏的菜单
  110. function moveSwipeAction(moveX, instance, ownerInstance) {
  111. var state = instance.getState()
  112. // 获取所有按钮的实例,需要通过它去设置按钮的位移
  113. var buttons = ownerInstance.selectAllComponents('.tn-swipe-action-item__right__button')
  114. // 设置菜单内容部分的偏移
  115. instance.requestAnimationFrame(function () {
  116. instance.setStyle({
  117. // 设置translateX的值
  118. 'transition': 'none',
  119. transform: 'translateX('+ moveX +'px)',
  120. '-webkit-transform': 'translateX('+ moveX +'px)'
  121. })
  122. })
  123. }
  124. // 一次性展开滑动菜单
  125. function openSwipeAction(instance, ownerInstance) {
  126. var state = instance.getState()
  127. // 获取所有按钮的实例,需要通过它去设置按钮的位移
  128. var buttons = ownerInstance.selectAllComponents('.tn-swipe-action-item__right__button')
  129. // 处理duration单位问题
  130. var duration = getDuration(state.duration)
  131. // 展开过程中,是向左移动,所以x的偏移应该是负值
  132. var buttonsWidth = -state.buttonsWidth
  133. instance.requestAnimationFrame(function () {
  134. // 设置菜单主体内容
  135. instance.setStyle({
  136. 'transition': 'transform ' + duration,
  137. 'transform': 'translateX('+ buttonsWidth +'px)',
  138. '-webkit-transform': 'translateX('+ buttonsWidth +'px)'
  139. })
  140. })
  141. setStatus('open', instance, ownerInstance)
  142. }
  143. // 一次性收起滑动菜单
  144. function closeSwipeAction(instance, ownerInstance) {
  145. var state = instance.getState()
  146. // 获取所有按钮的实例,需要通过它去设置按钮的位移
  147. var buttons = ownerInstance.selectAllComponents('.tn-swipe-action-item__right__button')
  148. var len = buttons.length
  149. // 处理duration单位问题
  150. var duration = getDuration(state.duration)
  151. instance.requestAnimationFrame(function () {
  152. // 设置菜单主体内容
  153. instance.setStyle({
  154. 'transition': 'transform ' + duration,
  155. 'transform': 'translateX(0px)',
  156. '-webkit-transform': 'translateX(0px)'
  157. })
  158. // 设置各个隐藏按钮的收起状态
  159. for (var i = len - 1; i >= 0; i--) {
  160. buttons[i].setStyle({
  161. 'transition': 'transform ' + duration,
  162. 'transform': 'translateX(0px)',
  163. '-webkit-transform': 'translateX(0px)'
  164. })
  165. }
  166. })
  167. setStatus('close', instance, ownerInstance)
  168. }
  169. // 标记菜单的当前状态,open - 打开 close - 关闭
  170. function setStatus(status, instance, ownerInstance) {
  171. var state = instance.getState()
  172. state.status = status
  173. ownerInstance.callMethod('setStatus', status)
  174. }
  175. // status的状态发生变化
  176. function statusChange(newValue, oldValue, ownerInstance, instance) {
  177. var state = instance.getState()
  178. if (state.disabled) return
  179. // 打开或关闭单元格
  180. if (newValue === 'close' && state.status === 'open') {
  181. closeSwipeAction(instance, ownerInstance)
  182. } else if (newValue === 'open' && state.status === 'close') {
  183. openSwipeAction(instance, ownerInstance)
  184. }
  185. }
  186. // 菜单尺寸发生变化
  187. function sizeChange(newValue, oldValue, ownerInstance, instance) {
  188. // wxs内的局部变量快照
  189. var state = instance.getState()
  190. state.disabled = newValue.disabled
  191. state.duration = newValue.duration
  192. state.show = newValue.show
  193. state.threshold = newValue.threshold
  194. state.buttons = newValue.buttons
  195. if (state.buttons) {
  196. var len = state.buttons.length
  197. var buttonsWidth = 0
  198. var buttons = newValue.buttons
  199. for (var i = 0; i < len; i++) {
  200. buttonsWidth += buttons[i].width
  201. }
  202. }
  203. state.buttonsWidth = buttonsWidth
  204. }
  205. module.exports = {
  206. touchStart: touchStart,
  207. touchMove: touchMove,
  208. touchEnd: touchEnd,
  209. sizeChange: sizeChange,
  210. statusChange: statusChange
  211. }