当你明白功能的实现逻辑的时候,往往实现的过程中会给你带来惊喜,所以先去明确功能的实现逻辑,剩下的事情会水到渠成
比如这个功能,开始的时候我是这样想的,第一张图片的左侧中点作为左侧触发边界点,右侧中点作为右侧触发边界点,当第一张图片的右侧边界点拖动到第二张图片的右半部分时,将第二张图片移动到左边,并交换两张图片的index和位置。当第二张图片的左侧边界点拖动到第一张图片的左半部分时,将第一张图片移动到右边,并较远两张图片的index和位置。但是实现后发现只能拖动一次,就是左边的拖到右边,右边的拖动到左边,出现第三张图片的时候就不行了,还有个问题就是拖动第一张图片到右边第二张图片移动到左边后,这时候拖动还没完成,再把第一张图片托回去后,移动到左边的第二张图片并不会回去。然后又想了想分别针对每张图片设置触发区间,当一张图片拖动时触发这些区间后移动,做着做着感觉做不动了。
然后又看了看微信的操作,发现是以每张图片的中心点做参考的,当你拖动一张图片的时候,其他图片的中心点就作为触发点,当其他图片的中心点处在拖动的图片内的时候把触发的图片和当前拖动的图片的index和位置互换。这样不考虑index顺序,当前拖动图片被动触发才是正确的思路
效果如下
代码如下,插入的图片元素需要有class和moveindex,插入后执行press函数,代码需要修改对应的图片class,moveindex属性对应上才能正常运行,主要还是看实现逻辑,有问题请提出,有不足和改进的建议也请提出
1 $.fn.press = function () { 2 var timeOutEvent = 0,startX,startY,offsetX,offsetY,moveX,moveY,imgOffsetTop,imgOffsetLeft,scrollTop,imgHeight,imgWidth,modalHeight,windowHeight,imgIndex,imgArr = [],imgStartOffsetLeft,imgStartOffsetTop,isLongPress; 3 var img = $(this); 4 var imgWidthHeight = img[0].clientWidth; 5 $.each($('.imgClass'),function (i,e) { 6 $(this).css({ 7 'position' : 'absolute', 8 'left' : e.offsetLeft, 9 'top' : e.offsetTop 10 }) 11 }) 12 $(img).on({ 13 touchstart: function(e){ 14 timeOutEvent = setTimeout(function(){ 15 timeOutEvent = 0; 16 $(img).css({'width':'3rem','height':'3rem'}); 17 imgStartOffsetLeft = $(img)[0].offsetLeft; 18 imgStartOffsetTop = $(img)[0].offsetTop; 19 startX = e.originalEvent.targetTouches[0].pageX; 20 startY = e.originalEvent.targetTouches[0].pageY; 21 offsetX = startX - imgStartOffsetLeft; 22 offsetY = startY - imgStartOffsetTop; 23 imgIndex = parseInt($(img).attr('moveindex')); 24 $(img).css({ 25 'position':'absolute', 26 'z-index':'200', 27 'left':imgStartOffsetLeft + 'px', 28 'top':imgStartOffsetTop + 'px' 29 }); 30 //防止微信露底 31 document.body.ontouchmove = function (e) { 32 e.preventDefault(); 33 }; 34 //阻止长按默认行为,比如微信长按图片弹出菜单 35 $(img).bind('contextmenu', function(e) { 36 e.preventDefault(); 37 }) 38 //获取当前所有图片的占位位置,为长按拖动后的移动做准备 39 $.each($('.imgClass'),function (i,e) { 40 var index = $(e).attr('moveindex'); 41 imgArr[index] = { 42 x1 : e.offsetLeft, 43 x2 : imgWidthHeight, 44 y1 : e.offsetTop, 45 y2 : imgWidthHeight, 46 trigger : { 47 x : e.offsetLeft + imgWidthHeight / 2, 48 y : e.offsetTop + imgWidthHeight / 2 49 } 50 }; 51 }) 52 isLongPress = true; 53 },200); 54 55 }, 56 touchmove: function(e){ 57 clearTimeout(timeOutEvent); 58 timeOutEvent = 0; 59 if(isLongPress) { 60 moveX = e.originalEvent.targetTouches[0].pageX; 61 moveY = e.originalEvent.targetTouches[0].pageY; 62 $(img).css({ 63 'left': moveX - offsetX + 'px', 64 'top': moveY - offsetY + 'px' 65 }) 66 imgOffsetTop = $(img)[0].offsetTop; 67 imgOffsetLeft = $(img)[0].offsetLeft; 68 scrollTop = document.body.scrollTop; 69 imgHeight = $(img)[0].offsetHeight; 70 imgWidth = $(img)[0].offsetWidth; 71 windowHeight = window.innerHeight; 72 73 74 //判断当前图片是否移动到其它图片上面 75 if (imgArr.length > 1) { 76 for(var i = 0;i < imgArr.length;i++){ 77 var trigger = imgArr[i].trigger; 78 if( i != imgIndex && trigger.x >= imgOffsetLeft && trigger.x <= (imgOffsetLeft + imgWidth) && trigger.y >= imgOffsetTop && trigger.y <= (imgOffsetTop + imgHeight)){ 79 $('.imgClass[moveindex=' + i + ']').css('position', 'absolute').attr('moveindex',imgIndex).animate({ 80 'left': imgArr[imgIndex].x1 + 'px', 81 'top': imgArr[imgIndex].y1 + 'px' 82 }, 300); 83 $(img).attr('moveindex', i); 84 imgIndex = i; 85 } 86 } 87 } 88 } 89 90 }, 91 touchend: function () { 92 clearTimeout(timeOutEvent); 93 if(isLongPress){ 94 var imgLeft = imgArr[ imgIndex ].x1 + 'px'; 95 var imgTop = imgArr[ imgIndex ].y1 + 'px'; 96 $(img).css({ 97 'position': 'absolute', 98 'width': '2.8rem', 99 'height': '2.8rem', 100 'left': imgLeft, 101 'top': imgTop, 102 'z-index': 0 103 }); 104 } 105 isLongPress = false; 106 document.body.ontouchmove = function (e) { 107 e.stopPropagation(); 108 }; 109 if(timeOutEvent != 0){ 110 console.log('单击了') 111 } 112 } 113 }) 114 }