index.sjs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /**
  2. * 此为sjs模块,专门为支付宝小程序设计
  3. * sjs语法与wxs基本相同,但有一些细微差别
  4. */
  5. // 开始触摸
  6. function touchstart(event, ownerInstance) {
  7. // 获取触发事件的组件实例
  8. var instance = event.instance;
  9. // 获取组件状态
  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. ownerInstance.callMethod('closeOther');
  21. }
  22. // 触摸滑动
  23. function touchmove(event, ownerInstance) {
  24. var instance = event.instance;
  25. var state = instance.getState();
  26. if (state.disabled || !state.moving) return;
  27. var touches = event.touches;
  28. var pageX = touches[0].pageX;
  29. var pageY = touches[0].pageY;
  30. var moveX = pageX - state.startX;
  31. var moveY = pageY - state.startY;
  32. var buttonsWidth = state.buttonsWidth;
  33. // 移动的X轴距离大于Y轴距离时,禁止页面滚动
  34. if (Math.abs(moveX) > Math.abs(moveY) || Math.abs(moveX) > state.threshold) {
  35. // 支付宝小程序阻止事件传播
  36. if (event.preventDefault) {
  37. event.preventDefault();
  38. }
  39. if (event.stopPropagation) {
  40. event.stopPropagation();
  41. }
  42. }
  43. // 如果Y轴移动距离大于X轴,认为是上下滑动
  44. if (Math.abs(moveX) < Math.abs(moveY)) return;
  45. // 限制滑动范围
  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) moveX = 0;
  56. // 限制最大滑动距离
  57. if (Math.abs(moveX) > buttonsWidth) moveX = -buttonsWidth;
  58. // 移动显示菜单
  59. moveSwipeAction(moveX, instance, ownerInstance);
  60. }
  61. }
  62. // 触摸结束
  63. function touchend(event, ownerInstance) {
  64. var instance = event.instance;
  65. var state = instance.getState();
  66. if (!state.moving || state.disabled) return;
  67. var touches = event.changedTouches ? event.changedTouches[0] : {};
  68. var pageX = touches.pageX;
  69. var moveX = pageX - state.startX;
  70. if (state.status === 'open') {
  71. // 展开状态下继续左滑无需操作
  72. if (moveX < 0) return;
  73. // 点击内容区域收起菜单
  74. if (moveX === 0) {
  75. return closeSwipeAction(instance, ownerInstance);
  76. }
  77. // 根据滑动距离决定是否关闭
  78. if (Math.abs(moveX) < state.threshold) {
  79. openSwipeAction(instance, ownerInstance);
  80. } else {
  81. closeSwipeAction(instance, ownerInstance);
  82. }
  83. } else {
  84. // 关闭状态下右滑无需操作
  85. if (moveX > 0) return;
  86. // 根据滑动距离决定是否打开
  87. if (Math.abs(moveX) < state.threshold) {
  88. closeSwipeAction(instance, ownerInstance);
  89. } else {
  90. openSwipeAction(instance, ownerInstance);
  91. }
  92. }
  93. }
  94. // 获取过渡时间
  95. function getDuration(value) {
  96. if (value.toString().indexOf('s') >= 0) return value;
  97. return value > 30 ? value + 'ms' : value + 's';
  98. }
  99. // 移动滑动选择器内容区域
  100. function moveSwipeAction(moveX, instance, ownerInstance) {
  101. var state = instance.getState();
  102. // 支付宝小程序获取按钮实例
  103. var buttons = ownerInstance.selectAllComponents('.u-swipe-action-item__right__button');
  104. // 设置内容部分的偏移
  105. instance.requestAnimationFrame(function() {
  106. instance.setStyle({
  107. transition: 'none',
  108. transform: 'translateX(' + moveX + 'px)',
  109. '-webkit-transform': 'translateX(' + moveX + 'px)'
  110. });
  111. });
  112. }
  113. // 展开滑动菜单
  114. function openSwipeAction(instance, ownerInstance) {
  115. var state = instance.getState();
  116. var buttons = ownerInstance.selectAllComponents('.u-swipe-action-item__right__button');
  117. var duration = getDuration(state.duration);
  118. var buttonsWidth = -state.buttonsWidth;
  119. instance.requestAnimationFrame(function() {
  120. instance.setStyle({
  121. transition: 'transform ' + duration,
  122. transform: 'translateX(' + buttonsWidth + 'px)',
  123. '-webkit-transform': 'translateX(' + buttonsWidth + 'px)'
  124. });
  125. });
  126. setStatus('open', instance, ownerInstance);
  127. }
  128. // 设置菜单状态
  129. function setStatus(status, instance, ownerInstance) {
  130. var state = instance.getState();
  131. state.status = status;
  132. ownerInstance.callMethod('setState', status);
  133. }
  134. // 收起滑动菜单
  135. function closeSwipeAction(instance, ownerInstance) {
  136. var state = instance.getState();
  137. var buttons = ownerInstance.selectAllComponents('.u-swipe-action-item__right__button');
  138. var len = buttons.length;
  139. var duration = getDuration(state.duration);
  140. instance.requestAnimationFrame(function() {
  141. // 设置菜单主体内容
  142. instance.setStyle({
  143. transition: 'transform ' + duration,
  144. transform: 'translateX(0px)',
  145. '-webkit-transform': 'translateX(0px)'
  146. });
  147. // 设置按钮为收起状态
  148. for (var i = len - 1; i >= 0; i--) {
  149. buttons[i].setStyle({
  150. transition: 'transform ' + duration,
  151. transform: 'translateX(0px)',
  152. '-webkit-transform': 'translateX(0px)'
  153. });
  154. }
  155. });
  156. setStatus('close', instance, ownerInstance);
  157. }
  158. // status状态变化处理
  159. function statusChange(newValue, oldValue, ownerInstance, instance) {
  160. var state = instance.getState();
  161. if (state.disabled) return;
  162. if (newValue === 'close' && state.status === 'open') {
  163. closeSwipeAction(instance, ownerInstance);
  164. } else if (newValue === 'open' && state.status === 'close') {
  165. openSwipeAction(instance, ownerInstance);
  166. }
  167. }
  168. // 菜单尺寸变化处理
  169. function sizeChange(newValue, oldValue, ownerInstance, instance) {
  170. var state = instance.getState();
  171. state.disabled = newValue.disabled;
  172. state.duration = newValue.duration;
  173. state.show = newValue.show;
  174. state.threshold = newValue.threshold;
  175. state.buttons = newValue.buttons;
  176. if (state.buttons) {
  177. var len = state.buttons.length;
  178. var buttonsWidth = 0;
  179. var buttons = newValue.buttons;
  180. for (var i = 0; i < len; i++) {
  181. buttonsWidth += buttons[i].width;
  182. }
  183. state.buttonsWidth = buttonsWidth;
  184. }
  185. }
  186. export default {
  187. touchstart,
  188. touchmove,
  189. touchend,
  190. statusChange,
  191. sizeChange
  192. };