pageing.sjs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. // 全局数据存储 - 优化状态管理
  2. var refreshState = {
  3. startY: 0,
  4. startTime: 0,
  5. refreshStatus: 1, // 1: 下拉刷新, 2: 释放刷新, 3: 刷新中, 4: 刷新完成
  6. refreshShow: false,
  7. readyRefresh: false,
  8. refresherThreshold: 40,
  9. currentReadyRefresh: true,
  10. isDragging: false,
  11. lastMoveY: 0,
  12. dragDistance: 0,
  13. velocity: 0,
  14. isTouchStarted: false,
  15. refresherEnabled: true
  16. };
  17. // 常量定义
  18. var CONSTANTS = {
  19. MIN_DRAG_DISTANCE: 10,
  20. MAX_DRAG_DISTANCE: 150,
  21. ANIMATION_DURATION: '0.3s',
  22. BOUNCE_DURATION: '0.2s',
  23. VELOCITY_THRESHOLD: 0.5,
  24. RESISTANCE_FACTOR: 0.6,
  25. EASING_FUNCTION: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)'
  26. };
  27. // 计算阻力效果
  28. function calculateResistance(distance, maxDistance) {
  29. if (distance <= maxDistance) {
  30. return distance;
  31. }
  32. return maxDistance + (distance - maxDistance) * CONSTANTS.RESISTANCE_FACTOR;
  33. }
  34. // 重置拖拽相关状态
  35. function resetDragState(state) {
  36. state.refreshShow = false;
  37. state.readyRefresh = false;
  38. state.isDragging = false;
  39. state.dragDistance = 0;
  40. state.velocity = 0;
  41. state.isTouchStarted = false;
  42. }
  43. // 设置容器样式
  44. function setContainerStyle(ins, transform, transition) {
  45. var container = ins.selectComponent('.u-paging__body');
  46. if (container) {
  47. container.setStyle({
  48. 'transform': transform,
  49. 'transition': transition
  50. });
  51. }
  52. }
  53. // 重置容器位置
  54. function resetContainerPosition(ins, useEasing) {
  55. var transition = useEasing ? CONSTANTS.ANIMATION_DURATION + ' ' + CONSTANTS.EASING_FUNCTION : CONSTANTS.ANIMATION_DURATION + ' ease-out';
  56. setContainerStyle(ins, 'translateY(0px)', transition);
  57. }
  58. // 触摸开始
  59. function touchstart(e, ins) {
  60. if (!refreshState.refresherEnabled) return;
  61. var touch = e.touches[0];
  62. // 重置状态
  63. refreshState.startY = touch.pageY;
  64. refreshState.startTime = Date.now();
  65. refreshState.isDragging = false;
  66. refreshState.dragDistance = 0;
  67. refreshState.velocity = 0;
  68. refreshState.lastMoveY = touch.pageY;
  69. refreshState.isTouchStarted = true;
  70. if (refreshState.currentReadyRefresh && refreshState.refreshStatus !== 3) {
  71. setContainerStyle(ins, 'translateY(0px)', '0s');
  72. }
  73. }
  74. // 触摸移动
  75. function touchmove(e, ins) {
  76. if (!refreshState.isTouchStarted || !refreshState.refresherEnabled ||
  77. !refreshState.currentReadyRefresh || refreshState.refreshStatus === 3) return;
  78. var touch = e.touches[0];
  79. var currentY = touch.pageY;
  80. var diffY = currentY - refreshState.startY;
  81. if (diffY <= 0) return;
  82. // 计算拖拽距离和速度
  83. refreshState.dragDistance = diffY;
  84. refreshState.velocity = (currentY - refreshState.lastMoveY) / (Date.now() - refreshState.startTime);
  85. refreshState.lastMoveY = currentY;
  86. refreshState.isDragging = true;
  87. // 应用阻力效果
  88. var resistedDistance = calculateResistance(diffY, CONSTANTS.MAX_DRAG_DISTANCE);
  89. var displayDistance = resistedDistance * CONSTANTS.RESISTANCE_FACTOR;
  90. // 更新状态
  91. if (displayDistance > CONSTANTS.MIN_DRAG_DISTANCE) {
  92. if (!refreshState.readyRefresh) {
  93. ins.callMethod('setReadyRefresh', { readyRefresh: true });
  94. refreshState.readyRefresh = true;
  95. }
  96. if (!refreshState.refreshShow) {
  97. ins.callMethod('setRefreshShow', { refreshShow: true });
  98. refreshState.refreshShow = true;
  99. }
  100. }
  101. // 设置变换
  102. setContainerStyle(ins, 'translateY(' + displayDistance + 'px)', '0s');
  103. // 更新刷新状态
  104. var newStatus = displayDistance >= refreshState.refresherThreshold ? 2 : 1;
  105. if (refreshState.refreshStatus !== newStatus) {
  106. ins.callMethod('setRefreshStatus', newStatus);
  107. refreshState.refreshStatus = newStatus;
  108. }
  109. }
  110. // 触摸结束
  111. function touchend(e, ins) {
  112. if (!refreshState.refresherEnabled || !refreshState.currentReadyRefresh || !refreshState.isDragging) return;
  113. // 重置拖拽状态
  114. refreshState.isDragging = false;
  115. ins.callMethod('setReadyRefresh', { readyRefresh: false });
  116. refreshState.readyRefresh = false;
  117. // 判断是否应该刷新
  118. var shouldRefresh = refreshState.refreshStatus === 2 ||
  119. (Math.abs(refreshState.velocity) > CONSTANTS.VELOCITY_THRESHOLD && refreshState.dragDistance > CONSTANTS.MIN_DRAG_DISTANCE);
  120. if (shouldRefresh) {
  121. // 触发刷新
  122. ins.callMethod('setRefreshStatus', 3);
  123. refreshState.refreshStatus = 3;
  124. // 动画到刷新位置
  125. setContainerStyle(ins, 'translateY(' + refreshState.refresherThreshold + 'px)',
  126. CONSTANTS.ANIMATION_DURATION + ' ' + CONSTANTS.EASING_FUNCTION);
  127. } else {
  128. // 回弹动画
  129. resetContainerPosition(ins, true);
  130. // 隐藏刷新指示器
  131. ins.callMethod('setRefreshShow', { refreshShow: false });
  132. refreshState.refreshShow = false;
  133. }
  134. // 重置拖拽相关状态
  135. refreshState.dragDistance = 0;
  136. refreshState.velocity = 0;
  137. refreshState.isTouchStarted = false;
  138. }
  139. // 刷新状态变化
  140. function refreshStatusChange(n, o, ins) {
  141. refreshState.refreshStatus = n;
  142. if (n === 4) {
  143. resetContainerPosition(ins, true);
  144. resetDragState(refreshState);
  145. }
  146. }
  147. // 刷新显示状态变化
  148. function refreshShowChange(n, o, ins) {
  149. refreshState.refreshShow = n;
  150. }
  151. // 准备刷新状态变化
  152. function readyRefreshChange(n, o, ins) {
  153. refreshState.readyRefresh = n;
  154. }
  155. // 刷新距离变化
  156. function refresherThresholdChange(n, o, ins) {
  157. refreshState.refresherThreshold = n || 40;
  158. }
  159. // 当前准备刷新状态变化
  160. function curReadyRefreshChange(n, o, ins) {
  161. refreshState.currentReadyRefresh = n;
  162. if (!n) {
  163. resetDragState(refreshState);
  164. resetContainerPosition(ins, false);
  165. }
  166. }
  167. // 下拉刷新启用状态变化
  168. function refresherEnabledChange(n, o, ins) {
  169. refreshState.refresherEnabled = n;
  170. if (!n) {
  171. resetDragState(refreshState);
  172. resetContainerPosition(ins, false);
  173. }
  174. }
  175. // 导出模块
  176. export default {
  177. touchstart,
  178. touchmove,
  179. touchend,
  180. refreshStatusChange,
  181. refreshShowChange,
  182. readyRefreshChange,
  183. refresherThresholdChange,
  184. curReadyRefreshChange,
  185. refresherEnabledChange
  186. };