drag.wxs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. var row_Height = 0; //行高
  2. var scrollOffsetTop = 0; //滚动条位置
  3. var isAppH5 = false; //是否APPH5端
  4. var isLongTouch = false; //是否开启长按
  5. var longTouchTime = 350; //触发长安事件事件
  6. var isMove = false; //是否可拖动
  7. var touchTimer=false; //长按事件定时器
  8. function scroll(event,instance){
  9. scrollOffsetTop = event.detail.scrollTop;
  10. }
  11. function touchstart(event, instance) {
  12. isMove = false;
  13. if(row_Height==0){
  14. var rowStyle = event.instance.getComputedStyle(['height']);
  15. row_Height = parseInt(rowStyle.height);//获取行高
  16. }
  17. var rowData = event.instance.getDataset();
  18. var rowtype = rowData.type == "A" ? "B" : "A";
  19. //重置样式
  20. resetRowStyle(state, instance, rowtype);
  21. var state = instance.getState();
  22. if (event.touches.length == 1) {
  23. state.point = event.touches[0];
  24. state.initscrollOffsetTop = scrollOffsetTop;
  25. state.islongTap = true;
  26. state.rowData = rowData;
  27. //读取数据
  28. var dataViewDOM = instance.selectComponent('#dataView');
  29. var viewData = dataViewDOM.getDataset();
  30. isAppH5 = viewData.isapph5&&JSON.parse(viewData.isapph5);
  31. isLongTouch = viewData.islongtouch&&JSON.parse(viewData.islongtouch);
  32. longTouchTime = parseInt(viewData.longtouchtime);
  33. state.rowData.rownum = viewData.rownum;
  34. state.rowData.listheight = viewData.listheight;
  35. }
  36. // 计算shadowRow.style.top
  37. var rowIndex = parseInt(rowData.index);
  38. var shadowRowTop = rowIndex*row_Height;
  39. shadowRowTop = shadowRowTop - scrollOffsetTop;
  40. // 加载shadowRow数据
  41. instance.callMethod("loadShadowRow", {rowIndex : rowIndex,shadowRowTop:shadowRowTop});
  42. state.shadowRowTop = shadowRowTop;
  43. var shadowBoxComponent = instance.selectComponent('#shadowRowBox');
  44. shadowBoxComponent.setStyle({'top': shadowRowTop + 'px'})
  45. //长按事件
  46. if(isLongTouch){
  47. if(typeof setTimeout !== "undefined"){
  48. touchTimer && clearTimeout(touchTimer);
  49. touchTimer = setTimeout(function(){
  50. longpress(event,instance);
  51. },longTouchTime)
  52. }
  53. }
  54. }
  55. function longpress(event,instance){
  56. if(isLongTouch){
  57. isMove = true;
  58. moveRow(instance, 0)
  59. }
  60. }
  61. function touchmove(event, instance) {
  62. var state = instance.getState();
  63. var rowData = event.instance.getDataset();
  64. var movePoint = event.touches[0];
  65. var initPoint = state.point;
  66. var moveY = movePoint.pageY - initPoint.pageY;
  67. if(isLongTouch){
  68. if(typeof setTimeout !== "undefined" && Math.abs(moveY)>10){
  69. clearTimeout(touchTimer);
  70. }
  71. if (!isMove) {
  72. return ;
  73. }
  74. }
  75. moveRow(instance, moveY);
  76. //阻止滚动页面
  77. if(event.preventDefault){
  78. event.preventDefault();
  79. }
  80. return false;
  81. }
  82. function touchend(event, instance) {
  83. if(isLongTouch && typeof setTimeout !== "undefined"){
  84. clearTimeout(touchTimer);
  85. }
  86. if(lastCommand!="stop"){
  87. lastCommand = "stop";
  88. instance.callMethod("pageScroll", {'command':"stop"});
  89. }
  90. var state = instance.getState();
  91. var rowtype = state.rowData.type;
  92. if (typeof state.offset !== "undefined" && state.rowData.index != state.offset && state.offset != null) {
  93. instance.callMethod("sort", {
  94. index: state.rowData.index,
  95. offset: state.offset
  96. });
  97. } else {
  98. resetRowStyle(state, instance, rowtype);
  99. resetShadowRowStyle(instance)
  100. feedbackGenerator(instance); //震动反馈
  101. return false;
  102. }
  103. resetShadowRowStyle(instance)
  104. typeof setTimeout !== "undefined" && setTimeout(function() {
  105. resetRowStyle(state, instance, rowtype);
  106. }, 500);
  107. state.offset = null;
  108. oldOffset = null;
  109. feedbackGenerator(instance); //震动反馈
  110. return false;
  111. }
  112. function resetRowStyle(state, instance, rowtype) {
  113. var blockList = instance.selectAllComponents('.row'+rowtype);
  114. for (var i = 0; i < blockList.length; i++) {
  115. blockList[i].setStyle({
  116. 'height': row_Height+'px',
  117. 'transform': 'none',
  118. '-webkit-transform': 'none'
  119. });
  120. blockList[i].removeClass('ani');
  121. blockList[i].removeClass('hide');
  122. }
  123. }
  124. function resetShadowRowStyle(instance) {
  125. var shadowBoxComponent = instance.selectComponent('#shadowRowBox');
  126. shadowBoxComponent.removeClass('show');
  127. shadowBoxComponent.setStyle({});
  128. shadowBoxComponent.removeClass('move');
  129. }
  130. var lastCommand = '';
  131. // move Row
  132. function moveRow(instance, moveY) {
  133. var state = instance.getState();
  134. var initIndex = parseInt(state.rowData.index);
  135. var rowtype = state.rowData.type;
  136. //显示拖拽行Box
  137. var shadowBoxComponent = instance.selectComponent('#shadowRowBox');
  138. shadowBoxComponent.hasClass('show') || shadowBoxComponent.addClass('show');
  139. //隐藏列表对应行
  140. var rowDom = instance.selectComponent('#row' + rowtype + state.rowData.index);
  141. rowDom.hasClass('hide') || rowDom.addClass('hide');
  142. //拖动shadowRow
  143. var shadowRowDom = instance.selectComponent('#shadowRow');
  144. shadowRowDom.hasClass('move') || shadowRowDom.addClass('move');
  145. shadowRowDom.removeClass('ani');
  146. var style = {
  147. 'transform': 'translateY(' + moveY + 'px) translateZ(10px)',
  148. '-webkit-transform': 'translateY(' + moveY + 'px) translateZ(10px)'
  149. }
  150. shadowRowDom.setStyle(style);
  151. var listheight = state.rowData.listheight
  152. var listClientY = state.shadowRowTop + moveY;
  153. var tmpscrollListTop = scrollOffsetTop;
  154. // 拖拽至边缘滚动视图 距离顶部距离1.5行高触发上滚动 下滚动同理
  155. var callMethodData = {
  156. command:listClientY<row_Height*1.5?"up":listClientY>listheight-(row_Height*1.5)?"down":"stop",
  157. scrollTop:tmpscrollListTop,
  158. }
  159. //把滚动指令发给逻辑层
  160. if(lastCommand!=callMethodData.command){
  161. lastCommand = callMethodData.command;
  162. instance.callMethod("pageScroll", callMethodData);
  163. }
  164. var moveOffset = moveY + scrollOffsetTop - state.initscrollOffsetTop;
  165. var offset = calcOffset(initIndex, moveOffset);
  166. if(offset<=2 || offset>=state.rowData.rownum-2){
  167. callMethodData.command = 'stop';
  168. }
  169. //为保证体验,非APP和H5端,在滚动视图期间不进行位置交换
  170. if((!isAppH5) && callMethodData.command!='stop'){
  171. return;
  172. }
  173. oldOffset = oldOffset == null ? initIndex : oldOffset;
  174. if (offset < 0 || offset >= state.rowData.rownum) {
  175. return;
  176. }
  177. if (offset == oldOffset) {
  178. return;
  179. }
  180. oldOffset = offset;
  181. state.offset = offset;
  182. //触发change事件
  183. instance.callMethod("change", {
  184. index: state.rowData.index,
  185. moveTo: state.offset
  186. });
  187. feedbackGenerator(instance); //震动反馈
  188. //根据offset对行进行位置交换
  189. var blockList = instance.selectAllComponents('.row' + rowtype);
  190. for (var i = 0; i < blockList.length; i++) {
  191. if (i == initIndex) {
  192. continue;
  193. }
  194. var translateY = 0;
  195. if ((i >= offset && i < initIndex) || (i <= offset && i > initIndex)) {
  196. translateY = i < initIndex ? row_Height : -row_Height;
  197. }
  198. var style = {
  199. 'height': row_Height+'px',
  200. 'transform': 'translateY(' + translateY + 'px) translateZ(5px)',
  201. '-webkit-transform': 'translateY(' + translateY + 'px) translateZ(5px)'
  202. }
  203. blockList[i].hasClass('ani') || blockList[i].addClass('ani');
  204. blockList[i].setStyle(style);
  205. }
  206. }
  207. //计算偏移index
  208. var oldOffset = null;
  209. function calcOffset(initIndex, moveY) {
  210. var offset = initIndex + parseInt(moveY / row_Height); //偏移 行高的倍数
  211. var rest = moveY % row_Height;
  212. if (rest > 0) {
  213. offset = offset + (rest / row_Height >= 0.6 ? 1 : 0);
  214. if (offset < oldOffset) {
  215. offset = rest / row_Height <= 0.4 ? offset : oldOffset;
  216. }
  217. } else {
  218. offset = offset + (rest / row_Height <= -0.6 ? -1 : 0);
  219. if (offset > oldOffset) {
  220. offset = rest / row_Height >= -0.4 ? offset : oldOffset;
  221. }
  222. }
  223. return offset;
  224. }
  225. //触感反馈
  226. //wxs 不支持条件编译,所以用此方法判断
  227. var isiOSAPP = typeof plus != "undefined" && plus.os.name == 'iOS';
  228. var UISelectionFeedbackGenerator;
  229. var UIImpactFeedbackGenerator;
  230. var impact
  231. if (isiOSAPP) {
  232. UISelectionFeedbackGenerator = plus.ios.importClass("UISelectionFeedbackGenerator");
  233. impact = new UISelectionFeedbackGenerator();
  234. impact.init();
  235. }
  236. function feedbackGenerator(instance) {
  237. if (isiOSAPP) {
  238. impact.selectionChanged();
  239. } else {
  240. if (typeof plus != "undefined") {
  241. plus.device.vibrate(12)
  242. } else {
  243. instance.callMethod("vibrate");
  244. }
  245. }
  246. }
  247. module.exports = {
  248. scroll:scroll,
  249. longpress:longpress,
  250. touchstart: touchstart,
  251. touchmove: touchmove,
  252. touchend: touchend
  253. }