解決這個(gè)問(wèn)題要考慮以下幾個(gè)因素:
1.被拖動(dòng)的節(jié)點(diǎn)是否脫離文檔流拂盯?
2.整個(gè)過(guò)程會(huì)觸發(fā)幾個(gè)事件?
a.被拖動(dòng)的節(jié)點(diǎn)是要脫離文檔流记靡,如果不脫離谈竿,節(jié)點(diǎn)會(huì)依照上一個(gè)節(jié)點(diǎn)來(lái)定位团驱,這樣就無(wú)法實(shí)現(xiàn)功能
b.為了實(shí)現(xiàn)拖動(dòng),基本方法是每次移動(dòng)空凸,計(jì)算出當(dāng)前節(jié)點(diǎn)的left和top值嚎花,然后添加到對(duì)應(yīng)節(jié)點(diǎn)的style中,對(duì)其進(jìn)行重新的定位和渲染
計(jì)算方法:(我們使用div做拖動(dòng))
首先需要知道javascript中關(guān)于尺寸的屬性:
clientWidth是對(duì)象看到的寬度(不含邊線,即border)
scrollWidth是對(duì)象實(shí)際內(nèi)容的寬度(若無(wú)padding呀洲,那就是邊框之間距離紊选,如有padding,就是左padding和右padding之間距離)道逗。
offsetWidth是指對(duì)象自身的寬度兵罢,整型,單位像素(含邊線滓窍,如滾動(dòng)條的占用的寬卖词,值會(huì)隨著內(nèi)容的輸入而不斷改變)。
offsetHeight:獲取對(duì)象相對(duì)于版面或由父坐標(biāo) offsetParent 屬性指定的父坐標(biāo)的高度
scrollHeight: 獲取對(duì)象的滾動(dòng)高度吏夯。
scrollLeft:設(shè)置或獲取位于對(duì)象左邊界和窗口中目前可見(jiàn)內(nèi)容的最左端之間的距離
scrollTop:設(shè)置或獲取位于對(duì)象最頂端和窗口中可見(jiàn)內(nèi)容的最頂端之間的距離
scrollWidth:獲取對(duì)象的滾動(dòng)寬度
offsetLeft:獲取對(duì)象相對(duì)于版面或由 offsetParent 屬性指定的父坐標(biāo)的計(jì)算左側(cè)位置
offsetTop:獲取對(duì)象相對(duì)于版面或由 offsetTop 屬性指定的父坐標(biāo)的計(jì)算頂端位置
clientX 設(shè)置或獲取鼠標(biāo)指針位置相對(duì)于當(dāng)前窗口的 x 坐標(biāo)此蜈,其中客戶區(qū)域不包括窗口自身的控件和滾動(dòng)條。
clientY 設(shè)置或獲取鼠標(biāo)指針位置相對(duì)于當(dāng)前窗口的 y 坐標(biāo)噪生,其中客戶區(qū)域不包括窗口自身的控件和滾動(dòng)條裆赵。
其次:拖動(dòng)的時(shí)候有一個(gè)變量是不變的,就是鼠標(biāo)指針到div的長(zhǎng)寬距離是不變的杠园,因此可以使用這個(gè)特性計(jì)算div所處的left和top值
綜上顾瞪,我們可將整個(gè)過(guò)程分成三個(gè)事件
1.按下鼠標(biāo)時(shí)的事件
這時(shí):指針當(dāng)前的位置 - div對(duì)象所在位置獲得那個(gè)常量
2.鼠標(biāo)拖動(dòng)的事件
這時(shí):a.指針當(dāng)前的位置 - 上一步驟獲得的常量就能得到div對(duì)象當(dāng)前所處位置
b.將得到的值填入到div對(duì)象style中,進(jìn)行重新渲染
3.松開鼠標(biāo)后的事件
將拖動(dòng)事件關(guān)閉
代碼展示:
css:
<style type="text/css">
#box{width: 100px;height: 100px; background-color: red;position: absolute;}
</style>
html:
<div id="box" ></div>
javascript:
<script type="text/javascript">
var box=document.getElementById('box');
box.onmousedown=function (ev) {
//考慮win8兼容性
var ev=ev||window.event;
//獲取指針到box對(duì)象(div)的left抛蚁、top距離
var a=ev.clientX-box.offsetLeft;
var b=ev.clientY-box.offsetTop;
document.onmousemove=function (ev) {
var ev=ev||window.event;
//獲取當(dāng)前box的位置
var c=ev.clientX-a;
var d=ev.clientY-b;
if(c<=0){
c=0;
}
if (d<=0) {
d=0;
}
//將得到的值載入
box.style.left=c+'px';
box.style.top=d+'px';
}
}
box.onmouseup=function () {
//將拖動(dòng)關(guān)閉
document.onmousemove=null;
}
</script>