第一步
首先簡單分析下需求吧,我們就是想實現滑鼠拖拽帶顏色的方塊時,讓方塊停留在滑鼠鬆開的位置,需要計算的就是拖拽前的座標和拖拽後的座標,滑鼠移動後相對於原位置的偏移量=目標元素的偏移量,根據這個等式和幾個屬性實現拖拽(下面會介紹到這幾個屬性,莫急哈,後面還會遇到一個小問題,一會詳細描述),滑鼠的狀態事件有三種,滑鼠按下時的事件(mousedown),滑鼠移動時的事件(mousemove),滑鼠鬆開時的事件(mouseup)
第二部
這裡就是擼程式碼了,首先新建一個html頁面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <style> #div{ position: absolute; width:100px; height: 100px; background-color: deeppink; } </style> <body style="border:1px solid #000;height: 600px;margin:0"> <div id="div"></div> <script> let tar=document.getElementById('div') let isDrag=false; tar.onmousedown=function(el){ var el= el || event; isDrag=true if(isDrag){ document.onmousemove=function(e){ var e = e || event; tar.style.left= e.clientX - el.offsetX + 'px'; tar.style.top= e.clientY - el.offsetY + 'px'; } } else { return } document.onmouseup=function(){ isDrag=false; // tar.onmousedown=null; document.onmousemove=null document.onmouseup=null } } </script> </body> </html>
這裡時完整的程式碼,我一步一步的來解釋
(1)<body style="border:1px solid #000;height: 600px;margin:0">這段程式碼起了個初始化的作用,(因為谷歌瀏覽器會預設給body加8px的margin)border加不加無所謂,我加上是方便看一下邊界;
(2)position: absolute; 樣式中的這個東西不能缺,因為只用元素定位了之後才能使用top和left屬性;
(3)頁面中的isDrag就相當於一個開關,只有當為true的時候才允許拖拽(也就是滑鼠按下的時候才能拖拽,鬆開時isDrag自動變為false,mousemove事件就不能觸發了)
(4)var e = e || event(window.event); 這行程式碼其實也很好理解,就是為了相容,它就相當於一個函式中運用三目給e重新賦值,
(function(event){ var e = event ? event : window.event })()
這樣理解就簡單了,上面說了個小問題是啥,現在可以揭曉了,把頁面中的var 換成let試一下,
瀏覽器控制檯報了一行錯,如下
Uncaught SyntaxError: Identifier 'el' has already been declared
(星星個b的),咋報錯了,為啥啊,咋回事啊? 趕緊百度一下壓壓驚,
不廢話了,簡單解釋下,這裡涉及到兩個知識點:函式的形參以及let和var宣告變數的區別,函式的形參也是函式作用域的引數,也就是函式呼叫後形成的區域性作用域內的引數,它不屬於全域性哦,也就相當於使用let宣告瞭這個引數,有人會問了,用var咋就可以呢,咋就不報錯呢,因為var宣告的變數會覆蓋掉同名變數(也就是覆蓋了形參),不要槓為啥覆蓋,js就是這麼定義的,百度下答案都是大同小異,王八的屁股--龜腚(規定),
tar.style.left= e.clientX - el.offsetX + 'px'; tar.style.top= e.clientY - el.offsetY + 'px';
這兩行程式碼就是計算元素的left和top的程式碼,position天天用,top和left不難理解,e.clientX就是滑鼠終點距離div左邊的垂直距離,e.clientY就是距離div上邊的垂直距離,
el.offsetX 是div距離瀏覽器左邊的距離,el.offsetY 是距離瀏覽器頁面顯示區的距離,頁面顯示區的上邊,標籤欄下面,有一條灰邊,滑鼠動的時候這四個值也是在不斷變化的,只要設定一下div的top和left就能實現簡單的拖拽功能了
(5)mouseup事件是釋放空間,節約記憶體。
這樣就完成了一個簡單的拖拽。後面再一起學習複雜拖拽(比方說,限制範圍,拖拽生成新的等等)
document.onmouseup=null