ps:代碼是其他提供,其中所有文字都是個(gè)人理解,如果有什么錯(cuò)誤和想法歡迎溝通~希望對(duì)你有幫助,biu
<h1>拖動(dòng) /拖曳效果</h1>
首先把需要拖動(dòng)的部分放到一個(gè)div里面,然后導(dǎo)入相關(guān)的.js文件
<code>
<div class="login_logo_webqq"></div>
</code>
由于IE10以上不支持document.getElementsClassName(),所以為了解決所有瀏覽器兼容的問題,需要把獲取ClassName封裝起來.
通過Class獲取元素需要兩個(gè)參數(shù),一個(gè)時(shí)ClassName類名,一個(gè)是父元素,第二個(gè)參數(shù)也不是必須的,如果不寫就打上document,就會(huì)尋找所有class的元素,寫了就尋找這個(gè)父元素下的ClassName.
function getByClass(clsName,parent){
var oParent=parent?document.getElementById(parent):document,
eles=[],
解釋:如果傳入parent就獲取他的id然后付給變量,沒有傳的話就放入document
由于類名可能不唯一,所以得到的是一個(gè)數(shù)組,就把他放到這個(gè)eles數(shù)組里面.
elements=oParent.getElementsByTagName('*');
```
現(xiàn)在獲取到父元素下面所有的元素,然后進(jìn)行遍歷
for(var i=0,l=elements.length;i<l;i++){
if(elements[i].className==clsName){
eles.push(elements[i]);
}
}
return eles;
}
現(xiàn)在我們得到了這塊元素之后,我們調(diào)用一個(gè)drag的函數(shù),來完成拖拽.
<h2>拖動(dòng)一共要經(jīng)歷三步
1>在標(biāo)題區(qū)域按下開始拖動(dòng)
2>在頁面中拖動(dòng)
3>釋放鼠標(biāo)的時(shí)候停止拖動(dòng)
</h2>
window.onload=drag;
function drag(){
var oTitle=getByClass('login_logo_webqq','loginPanel')[0];
拖曳,獲取了這個(gè)div,
oTitle.onmousedown=fnDown;
```
onmousedown:在用戶按下任意鼠標(biāo)按鈕時(shí)出發(fā)事件fndown,為了方便閱讀我將fnDown函數(shù)放到下面.<h3>拖動(dòng)的原理其實(shí)就是拖動(dòng)的部分和你的光標(biāo)的坐標(biāo)是一樣的.</h3>
光標(biāo)的位置可以通過clientX 和 clientY來得到.
鼠標(biāo)事件都是在瀏覽器的特定位置上發(fā)生的,這個(gè)位置的信息保存在事件的clientX和clientY屬性中.所有瀏覽器都支持這兩個(gè)屬性,他們的值表示事件發(fā)生時(shí)鼠標(biāo)指針在視口中的水平和垂直坐標(biāo),不包括頁面滾動(dòng)的距離,也就是說可以通過這兩個(gè)屬性獲得光標(biāo)的xy坐標(biāo),然后讓彈框也是這個(gè)坐標(biāo)不就實(shí)現(xiàn)了拖動(dòng)
function fnDown(event){
event = event || window.event;
var oDrag=document.getElementById('loginPanel'),
// 光標(biāo)按下時(shí)光標(biāo)和面板之間的距離
disX=event.clientX-oDrag.offsetLeft,
disY=event.clientY-oDrag.offsetTop;
//用來獲取彈框左上角相對(duì)瀏覽器距離,下面會(huì)解釋
document.onmousemove=function(event){
event = event || window.event;
//IE得用window.event,得到事件對(duì)象
fnMove(event,disX,disY);
function fnMove(e,posX,posY){
var oDrag=document.getElementById('loginPanel'),//改變他得先把他取出來
```
<p>
<h5>錯(cuò)誤演示:</h5>
按理來說只要改變他的位置定位就可以了
oDrag.style.left = event.clientX+'px';
oDrang.style.top = event.clientY+'px';
<p>
這樣操作會(huì)明顯發(fā)現(xiàn),當(dāng)你光標(biāo)在拖動(dòng)區(qū)域按下鼠標(biāo)時(shí),光標(biāo)會(huì)跑到彈框的左上角,這樣的話用戶體驗(yàn)就不太好了.
bug分析:
由于你告訴瀏覽器光標(biāo)在哪,彈框在那,得有個(gè)標(biāo)準(zhǔn)吧,所以就是時(shí)你的彈框左上角和光標(biāo)位置一樣.而且你本身定義的top和left就是左上角的位置.
<h5>解決方案:</h5>
所以就是說我們不能直接告訴他讓和光標(biāo)一個(gè)位置,而是在你光標(biāo)按下的位置上的基礎(chǔ)來改變位置.所以就是要獲取到按下鼠標(biāo)的位置和左上角的位置有什么關(guān)系,在這個(gè)基礎(chǔ)上改變位置.

其中黃色的時(shí)光標(biāo),藍(lán)色時(shí)標(biāo)題框,其中的白線就是我們要獲取的坐標(biāo).而白線的距離就是光標(biāo)相對(duì)瀏覽器的距離減去彈框跟窗口之間的距離

</p>
</p>
l=e.clientX-posX,
t=e.clientY-posY,
l,t現(xiàn)在是獲得的白線的距離
注意任何拖動(dòng)的拖動(dòng)的東西,都需要一個(gè)絕對(duì)定位,在css中.
<p>
<h5>錯(cuò)誤發(fā)現(xiàn):</h5>
那現(xiàn)在又會(huì)發(fā)現(xiàn),彈框可以任意拖動(dòng),也就是可以一直把滾動(dòng)條撐起來,這樣的話用戶體驗(yàn)也不好
<h5>分析解決:</h5>
我們現(xiàn)在就需要,當(dāng)彈框接觸瀏覽器邊界的時(shí)候不能在想外拖動(dòng)了.所以就用限制一個(gè)范圍,不能隨意拉動(dòng)了.對(duì)于左邊也就時(shí)lt變成負(fù)數(shù)的時(shí)候讓他強(qiáng)制變成0.對(duì)于右邊就拖動(dòng)的最大范圍就是頁面寬減去彈框?qū)挾?當(dāng)坐標(biāo)大于這個(gè)范圍的時(shí)候就強(qiáng)制變成最大坐標(biāo)
</p>
winW=document.documentElement.clientWidth || document.body.clientWidth,
winH=document.documentElement.clientHeight || document.body.clientHeight,
maxW=winW-oDrag.offsetWidth-10,
//這里減10是因?yàn)殛P(guān)閉按鈕允許溢出十個(gè)像素
maxH=winH-oDrag.offsetHeight;
if(l<0){
l=0;
}else if(l>maxW){
l=maxW;
}
if(t<0){
t=10;
//這樣才能底對(duì)齊
}else if(t>maxH){
t=maxH;
}
oDrag.style.left=l+'px';
oDrag.style.top=t+'px';
}
}
onmousemove當(dāng)鼠標(biāo)指針在元素內(nèi)部移動(dòng)時(shí)重復(fù)地觸發(fā),也就是每移動(dòng)一下都會(huì)觸發(fā)這個(gè)事件.
// mouseup當(dāng)用戶釋放鼠標(biāo)觸發(fā)事件
document.onmouseup=function(){
document.onmousemove=null;
//就是移動(dòng)的時(shí)候什么也不做,釋放事件
document.onmouseup=null;
}
}
<h4>總結(jié)</h4>
總的來說就是獲取到可以點(diǎn)擊鼠標(biāo)拖動(dòng)的區(qū)域,然后再處理好彈框和鼠標(biāo)坐標(biāo)的關(guān)系.放開鼠標(biāo)的時(shí)候釋放事件.最后再處理一下邊界的問題就好了.我個(gè)人認(rèn)為這個(gè)這個(gè)坐標(biāo)的問題還是很值得分析的.