當你明白功能的實現邏輯的時候,往往實現的過程中會給你帶來驚喜,所以先去明確功能的實現邏輯,剩下的事情會水到渠成
比如這個功能,開始的時候我是這樣想的,第一張圖片的左側中點作為左側觸發邊界點,右側中點作為右側觸發邊界點,當第一張圖片的右側邊界點拖動到第二張圖片的右半部分時,將第二張圖片移動到左邊,並交換兩張圖片的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 }