之前在聊天群里看到有人說面試的時候被問到了怎樣實現一個拖拽效果,當時看到后在心里默默思考了下,結果發現好像我也寫不出來啊。本着遇到一個解決一個的思想,就親自敲了一個,看到張鑫旭大神寫的代碼,真的很厲害,多多學習了,(感覺隨便搜一個關於前端方面的問題都能看到他的網站,真是太佩服了,寫了那么多文章,十分感謝。)
好了,接下來就進入正題了。
想實現一個效果首先得明白其中的邏輯,知道了實現邏輯后,就可以碼代碼了。
首先我實現的效果是:
- 鼠標按下后,才可以執行后續效果
- 鼠標已經按下,然后鼠標移動,需要拖拽的元素跟着一起移動
- 鼠標松開,然后停止移動
大步驟就是這樣一個過程,其實對應的就是三個事件:
- onmousedown
- onmousemove
- onmouseup
然后我們來看這三個事件發生時分別作做什么事。
當鼠標按下時,我們得記錄當前元素的位置newSite。同時設置一個標記,用於表示此時鼠標時按下的狀態,方便鼠標移動事件的執行。
當鼠標松開時,我們要將標記改變,說明此時鼠標松開了,當鼠標移動時就不能再移動元素了。
當鼠標按下並且移動時,我們就要記錄鼠標每次移動的位置currentSite,currentSite和newSite的差值就是鼠標移動的距離,同時也是元素應該移動的距離,然后設置元素的位置就OK了。
當然有個很重要的點就是需要移動的元素的position屬性應該設為absolute或者relative,這樣元素才可以移動。
同時,如果該元素內部有可能導致瀏覽器默認事件發生的元素時,要阻止默認事件的發生,例如里面有一個圖片時,點擊拖動的時候瀏覽器會默認彈出一個新窗口顯示該圖片,這時我們應該阻止這個事件的發生。具體方式可以查看代碼。
具體演示可查看:http://www.w3cfuns.com/notes/19044/b3c57594c1f1b220f1a102d4e9147828.html

1 // 參數列表 2 var params = { 3 left: 0, 4 top: 0, 5 currentX: 0, 6 currentY: 0, 7 flag: false 8 }; 9 //獲取相關CSS屬性 10 var getCss = function(o, key) { 11 // getComputedStyle是為了兼容FF瀏覽器 12 return o.currentStyle ? o.currentStyle[key] : document.defaultView.getComputedStyle(o, false)[key]; 13 }; 14 15 //拖拽的實現 16 var startDrag = function(target, callback) { 17 // 首先獲取目標元素的left、top屬性值 18 if (getCss(target, "left") !== "auto") { 19 params.left = getCss(target, "left"); 20 } 21 if (getCss(target, "top") !== "auto") { 22 params.top = getCss(target, "top"); 23 } 24 25 target.onmousedown = function(event) { 26 // 當鼠標按下時表示元素可以移動,將標記設為true; 27 params.flag = true; 28 29 /*為了阻止拖動瀏覽器中元素時發生默認事件, 30 例如拖動圖片時會出現一個新窗口顯示該圖片,下面代碼可以阻止這種事件發生 31 */ 32 if (event.preventDefault) { 33 event.preventDefault(); 34 }else { 35 event.returnValue = false; 36 } 37 38 var e = event; 39 params.currentX = e.clientX; 40 params.currentY = e.clientY; 41 }; 42 target.onmouseup = function() { 43 // 當鼠標松開時將標記設為false,表示不可移動 44 params.flag = false; 45 // 當鼠標松開時再次更新元素的位置 46 if (getCss(target, "left") !== "auto") { 47 params.left = getCss(target, "left"); 48 } 49 if (getCss(target, "top") !== "auto") { 50 params.top = getCss(target, "top"); 51 } 52 }; 53 target.onmousemove = function(event) { 54 var e = event ? event : window.event; 55 /*當params.flag==true時才可以移動,表明此時鼠標時按下狀態 56 */ 57 if (params.flag) { 58 // 獲取到當前鼠標的位置 59 var nowX = e.clientX, 60 nowY = e.clientY; 61 // 獲取當前鼠標移動的距離,即當前鼠標位置減去初始位置 62 var disX = nowX - params.currentX, 63 disY = nowY - params.currentY; 64 // 將元素的位置更新,parsenInt為了將屬性值變為數字類型 65 target.style.left = parseInt(params.left) + disX + "px"; 66 target.style.top = parseInt(params.top) + disY + "px"; 67 } 68 } 69 };