| var classPrefix = ''; | 
| var startIndex = 0; | 
| var endIndex = 0; | 
| var dragCollisionList = []; | 
|   | 
| var isOutRange = function (x1, y1, x2, y2, x3, y3) { | 
|   return x1 < 0 || x1 >= y1 || x2 < 0 || x2 >= y2 || x3 < 0 || x3 >= y3; | 
| }; | 
|   | 
| var sortCore = function (sKey, eKey, st) { | 
|   var _ = st.dragBaseData; | 
|   | 
|   var excludeFix = function (cKey, type) { | 
|     if (st.list[cKey].fixed) { | 
|       // fixed 元素位置不会变化, 这里直接用 cKey(sortKey) 获取, 更加快捷 | 
|       type ? --cKey : ++cKey; | 
|       return excludeFix(cKey, type); | 
|     } | 
|     return cKey; | 
|   }; | 
|   | 
|   // 先获取到 endKey 对应的 realKey, 防止下面排序过程中该 realKey 被修改 | 
|   var endRealKey = -1; | 
|   st.list.forEach(function (item) { | 
|     if (item.sortKey === eKey) endRealKey = item.realKey; | 
|   }); | 
|   | 
|   return st.list.map(function (item) { | 
|     if (item.fixed) return item; | 
|     var cKey = item.sortKey; | 
|     var rKey = item.realKey; | 
|   | 
|     if (sKey < eKey) { | 
|       // 正序拖动 | 
|       if (cKey > sKey && cKey <= eKey) { | 
|         --rKey; | 
|         cKey = excludeFix(--cKey, true); | 
|       } else if (cKey === sKey) { | 
|         rKey = endRealKey; | 
|         cKey = eKey; | 
|       } | 
|     } else if (sKey > eKey) { | 
|       // 倒序拖动 | 
|       if (cKey >= eKey && cKey < sKey) { | 
|         ++rKey; | 
|         cKey = excludeFix(++cKey, false); | 
|       } else if (cKey === sKey) { | 
|         rKey = endRealKey; | 
|         cKey = eKey; | 
|       } | 
|     } | 
|   | 
|     if (item.sortKey !== cKey) { | 
|       item.tranX = (cKey % _.columns) * 100 + '%'; | 
|       item.tranY = Math.floor(cKey / _.columns) * 100 + '%'; | 
|       item.sortKey = cKey; | 
|       item.realKey = rKey; | 
|     } | 
|     return item; | 
|   }); | 
| }; | 
|   | 
| var triggerCustomEvent = function (list, type, ins) { | 
|   var _list = [], | 
|     listData = []; | 
|   | 
|   list.forEach(function (item) { | 
|     _list[item.sortKey] = item; | 
|   }); | 
|   | 
|   _list.forEach(function (item) { | 
|     if (!item.extraNode) { | 
|       listData.push(item.data); | 
|     } | 
|   }); | 
|   | 
|   ins.triggerEvent(type, { listData: listData }); | 
| }; | 
|   | 
| var longPress = function (event, ownerInstance) { | 
|   var ins = event.instance; | 
|   var st = ownerInstance.getState(); | 
|   var _ = st.dragBaseData; | 
|   | 
|   var sTouch = event.changedTouches[0]; | 
|   if (!sTouch) return; | 
|   | 
|   st.cur = ins.getDataset().index; | 
|   longPressIndex = st.cur; | 
|   | 
|   // 初始项是固定项则返回 | 
|   var item = st.list[st.cur]; | 
|   if (item && item.fixed) return; | 
|   | 
|   // 如果已经在 drag 中则返回, 防止多指触发 drag 动作, touchstart 事件中有效果 | 
|   if (st.dragging) return; | 
|   st.dragging = true; | 
|   ownerInstance.callMethod('dragStatusChange', { dragging: true }); | 
|   | 
|   // 计算X,Y轴初始位移, 使 item 中心移动到点击处, 单列时候X轴初始不做位移 | 
|   st.tranX = _.columns === 1 ? 0 : sTouch.pageX - (_.itemWidth / 2 + _.wrapLeft); | 
|   st.tranY = sTouch.pageY - (_.itemHeight / 2 + _.wrapTop); | 
|   st.sId = sTouch.identifier; | 
|   ins.setStyle({ | 
|     transform: 'translate3d(' + st.tranX + 'px, ' + st.tranY + 'px, 0)', | 
|   }); | 
|   st.itemsInstance.forEach(function (item, index) { | 
|     item.removeClass(classPrefix + '__drag--tran').removeClass(classPrefix + '__drag--cur'); | 
|     item.addClass(index === st.cur ? classPrefix + '__drag--cur' : classPrefix + '__drag--tran'); | 
|   }); | 
|   ownerInstance.callMethod('dragVibrate', { vibrateType: 'longPress' }); | 
| }; | 
|   | 
| var touchMove = function (event, ownerInstance) { | 
|   var ins = event.instance; | 
|   var st = ownerInstance.getState(); | 
|   var _ = st.dragBaseData; | 
|   | 
|   var mTouch = event.changedTouches[0]; | 
|   if (!mTouch) return; | 
|   | 
|   if (!st.dragging) return; | 
|   | 
|   // 如果不是同一个触发点则返回 | 
|   if (st.sId !== mTouch.identifier) return; | 
|   | 
|   // 计算X,Y轴位移, 单列时候X轴初始不做位移 | 
|   var tranX = _.columns === 1 ? 0 : mTouch.pageX - (_.itemWidth / 2 + _.wrapLeft); | 
|   var tranY = mTouch.pageY - (_.itemHeight / 2 + _.wrapTop); | 
|   | 
|   // 到顶到底自动滑动 | 
|   if (mTouch.clientY > _.windowHeight - _.itemHeight - _.realBottomSize) { | 
|     // 当前触摸点pageY + item高度 - (屏幕高度 - 底部固定区域高度) | 
|     ownerInstance.callMethod('pageScroll', { | 
|       scrollTop: mTouch.pageY + _.itemHeight - (_.windowHeight - _.realBottomSize), | 
|     }); | 
|   } else if (mTouch.clientY < _.itemHeight + _.realTopSize) { | 
|     // 当前触摸点pageY - item高度 - 顶部固定区域高度 | 
|     ownerInstance.callMethod('pageScroll', { | 
|       scrollTop: mTouch.pageY - _.itemHeight - _.realTopSize, | 
|     }); | 
|   } | 
|   | 
|   // 设置当前激活元素偏移量 | 
|   ins.setStyle({ | 
|     transform: 'translate3d(' + tranX + 'px, ' + tranY + 'px, 0)', | 
|   }); | 
|   | 
|   var startKey = st.list[st.cur].sortKey; | 
|   var curX = Math.round(tranX / _.itemWidth); | 
|   var curY = Math.round(tranY / _.itemHeight); | 
|   var endKey = curX + _.columns * curY; | 
|   | 
|   // 目标项是固定项则返回 | 
|   var item = st.list[endKey]; | 
|   if (item && item.fixed) return; | 
|   | 
|   // X轴或Y轴超出范围则返回 | 
|   if (isOutRange(curX, _.columns, curY, _.rows, endKey, st.list.length)) return; | 
|   | 
|   // 防止拖拽过程中发生乱序问题 | 
|   if (startKey === endKey || startKey === st.preStartKey) return; | 
|   st.preStartKey = startKey; | 
|   | 
|   dragCollisionList = sortCore(startKey, endKey, st); | 
|   startIndex = startKey; | 
|   endIndex = endKey; | 
|   st.itemsInstance.forEach(function (itemIns, index) { | 
|     var item = dragCollisionList[index]; | 
|     if (index !== st.cur) { | 
|       itemIns.setStyle({ | 
|         transform: 'translate3d(' + item.tranX + ',' + item.tranY + ', 0)', | 
|       }); | 
|     } | 
|   }); | 
|   | 
|   ownerInstance.callMethod('dragVibrate', { vibrateType: 'touchMove' }); | 
|   ownerInstance.callMethod('dragCollision', { | 
|     dragCollisionList: dragCollisionList, | 
|     startIndex: startIndex, | 
|     endIndex: endIndex, | 
|   }); | 
|   triggerCustomEvent(dragCollisionList, 'change', ownerInstance); | 
| }; | 
|   | 
| var touchEnd = function (event, ownerInstance) { | 
|   var ins = event.instance; | 
|   var st = ownerInstance.getState(); | 
|   | 
|   if (!st.dragging) return; | 
|   triggerCustomEvent(st.list, 'sortend', ownerInstance); | 
|   ins.addClass(classPrefix + '__drag--tran'); | 
|   ins.setStyle({ | 
|     transform: 'translate3d(' + st.list[st.cur].tranX + ',' + st.list[st.cur].tranY + ', 0)', | 
|   }); | 
|   st.preStartKey = -1; | 
|   st.dragging = false; | 
|   ownerInstance.callMethod('dragStatusChange', { dragging: false }); | 
|   ownerInstance.callMethod('dragEnd', { | 
|     dragCollisionList: dragCollisionList, | 
|     startIndex: startIndex, | 
|     endIndex: endIndex, | 
|   }); | 
|   st.cur = -1; | 
|   st.tranX = 0; | 
|   st.tranY = 0; | 
| }; | 
|   | 
| var baseDataObserver = function (newVal, oldVal, ownerInstance, ins) { | 
|   var st = ownerInstance.getState(); | 
|   st.dragBaseData = newVal; | 
|   classPrefix = newVal.classPrefix; | 
| }; | 
|   | 
| var listObserver = function (newVal, oldVal, ownerInstance, ins) { | 
|   var st = ownerInstance.getState(); | 
|   st.itemsInstance = ownerInstance.selectAllComponents('.' + classPrefix + '__drag-item'); | 
|   st.list = newVal || []; | 
|   st.list.forEach(function (item, index) { | 
|     var itemIns = st.itemsInstance[index]; | 
|     if (item && itemIns) { | 
|       itemIns.removeClass(classPrefix + '__drag--tran'); | 
|       itemIns.setStyle({ | 
|         transform: 'translate3d(' + item.tranX + ',' + item.tranY + ', 0)', | 
|       }); | 
|       if (item.fixed) itemIns.addClass(classPrefix + '__drag--fixed'); | 
|     } | 
|   }); | 
|   dragCollisionList = []; | 
| }; | 
|   | 
| module.exports = { | 
|   longPress: longPress, | 
|   touchMove: touchMove, | 
|   touchEnd: touchEnd, | 
|   baseDataObserver: baseDataObserver, | 
|   listObserver: listObserver, | 
| }; |