drag.wxs 9.5 KB

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