JavaScript拖拽實(shí)現(xiàn)
背景
在學(xué)習(xí)開發(fā)了簽名板之后,為了更加一步學(xué)習(xí)和理解事件的位置坐標(biāo)這一塊的知識(shí)點(diǎn)苞七,自己用原生的js實(shí)現(xiàn)了一個(gè)可以拖拽的div框忆肾。
功能分析
首先白指,需要有一個(gè)可拖拽的對(duì)象较坛,如圖,一個(gè)比較簡(jiǎn)陋的拖拽框:
在這個(gè)框中扒最。我們只能在標(biāo)題欄部分才可以進(jìn)行拖拽丑勤,拖拽分為三步驟:
1、鼠標(biāo)在標(biāo)題欄部分按下后可以進(jìn)行拖拽
2吧趣、移動(dòng)按下的鼠標(biāo)法竞,拖拽框也會(huì)跟著移動(dòng)
3、鼠標(biāo)松開强挫,拖拽結(jié)束岔霸。
功能實(shí)現(xiàn)
通過上述的功能分析,可以將功能分為mousedown,mousemove,mouseup三個(gè)部分俯渤。下面一步一步對(duì)拖拽功能進(jìn)行分解呆细。
變量初始化
下面代碼為這個(gè)功能需要聲明的對(duì)象和變量等
var flag = false; // flag用來標(biāo)志鼠標(biāo)是否在標(biāo)題欄部分按下去
var wrap = document.getElementById('wrap'); // 獲取到整個(gè)拖拽框?qū)ο? var head = document.getElementById('tzHead'); // 獲取到拖拽框中標(biāo)題欄對(duì)象
var now = {
x:'',
y:''
}; // 當(dāng)前的鼠標(biāo)位置
var last = {
x:'',
y:''
}; // 鼠標(biāo)按下的時(shí)候的鼠標(biāo)位置
var initPosition = {
x:'',
y:''
}; // 鼠標(biāo)按下時(shí)的拖拽框相對(duì)偏移的位置
事件綁定
head.addEventListener('mousedown',beginDrag,false);
head.addEventListener('mousemove',drag,false);
head.addEventListener('mouseup',endDrag,false);
方法實(shí)現(xiàn)
1、開始拖拽方法:
function beginDrag(e) {
flag = true;
last.x = e.pageX;
last.y = e.pageY;
initPosition = {
x: wrap.offsetLeft,
y: wrap.offsetTop
};
}
2八匠、拖拽方法:
function drag(e) {
if (flag) {
now = {
x: e.pageX,
y: e.pageY
};
wrap.style.left = parseInt(now.x) - parseInt(last.x) + parseInt(initPosition.x) + 'px';
wrap.style.top = parseInt(now.y) - parseInt(last.y) + parseInt(initPosition.y) + 'px';
return false;
}
}
3絮爷、結(jié)束拖拽
function endDrag(e) {
flag = false;
}
問題
現(xiàn)在已經(jīng)實(shí)現(xiàn)了最基本的拖拽功能趴酣。可是這時(shí)候會(huì)有一個(gè)問題坑夯,就是如果我們鼠標(biāo)滑動(dòng)的很快岖寞,就很容易鼠標(biāo)從head區(qū)域出來,然后出來后松開鼠標(biāo)柜蜈,下次在head區(qū)域內(nèi)不用點(diǎn)擊就可以移動(dòng)拖拽框仗谆,這樣非常不友好。
優(yōu)化
針對(duì)上面這種情況淑履,在好好看了看代碼后發(fā)現(xiàn)隶垮。下面這段代碼是有問題的:
head.addEventListener('mousedown',beginDrag,false);
head.addEventListener('mousemove',drag,false);
head.addEventListener('mouseup',endDrag,false);
對(duì)于鼠標(biāo)按下事件,必須要綁定在head區(qū)域鳖谈∷晏郏可是拖拽事件和鼠標(biāo)松開事件應(yīng)該針對(duì)于整個(gè)文檔。于是改為
head.addEventListener('mousedown',beginDrag,false);
document.addEventListener('mousemove',drag,false);
document.addEventListener('mouseup',endDrag,false);
上述問題不存在了缆娃。
后續(xù)優(yōu)化
對(duì)于代碼功能而言已經(jīng)完成了功能捷绒,但是代碼質(zhì)量需要很大程度的優(yōu)化。