幾個與定位有關的概念:
js:
clientX/clientY屬性:獲得事件發生時鼠標指針在視口中的水平和垂直坐標。
screenX/screenY屬性:獲取鼠標事件發生時鼠標光標相對於整個電腦屏幕的坐標信息。
pageX/pageY屬性:可以獲得鼠標事件發生時鼠標光標相對於整個文檔元素的坐標位置(包含滾動)。在頁面沒有滾動的情況下,通常pageX/pageY的值與clientX/clientY的值相等。
layerX/layerY屬性:他是對於絕對定位元素來說的,相對於當前點擊元素的左上角定位的。當頁面上的元素時相對定位(position:relative)的時候,通常pageX/pageY和layerX/layerY的值是相同的,但是當元素絕對定位(position:absolute)了的時候,layerX/layerY就將鼠標光標位置相對於本身的左上角定位了。
jquery:
position()
獲取匹配元素相對父元素的偏移。
返回的對象包含兩個整型屬性:top 和 left。為精確計算結果,請在補白、邊框和填充屬性上使用像素單位。此方法只對可見元素有效。
offset()
獲取匹配元素在當前視口的相對偏移。
返回的對象包含兩個整型屬性:top 和 left,以像素計。此方法只對可見元素有效。
event.pageX
鼠標相對於文檔的左邊緣的位置。
event.pageY
鼠標相對於文檔的上邊緣的位置。
原理:
1.鼠標在彈出框上按下時,獲取鼠標相對於彈出框的left和top值l、t,這時彈出框狀態改為可拖動(mousedown事件)
2.當彈出框狀態為可拖動時:(mousemove事件)
①重新定位彈出框的位置;(獲取鼠標相對於可視區域的left和top值L、T,並且彈出的坐標移動,它的offsetLeft為L-l;offsetTop為T-t)
②限定彈出框的運動范圍;
3.當鼠標按鈕彈起時,彈出框不在移動,即狀態改為不可拖動;(mouseup)
實例:
HTML:

<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>鼠標拖拽事件</title> <style> *{ margin:0; padding: 0; } #container{ width: 380px; border: 1px solid #999; position: absolute; z-index: 5; } #mask{ position: absolute; height:100%; width: 100%; background: black; opacity: 0.6; /*filter:alpha(opacity=40);*/ z-index: 1; left: 0; top:0; } #top{ background: #ccc; height: 30px; cursor: pointer; } #content{ height: 100px; line-height: 20px; background: #fff; padding: 20px 0 0 0; } p{ text-align: center; } </style> <script src='demo.js'></script> <body> <div id='mask'></div> <div id='container'> <div id='top'></div> <div id='content'> <p><label>請輸入用戶名</label><input type='text' class='ipt'></p> <p><label> 請輸入密碼</label><input type='password' class='ipt'></p> </div> </div> </body> </html>
JS:

window.onload=function(){ var container=document.getElementById('container'); var top=document.getElementById('top'); var oMask=document.getElementById('mask') console.log(container); var startX ; var startY; var flag=false; top.onmousedown=function(e){ var e= e||window.event; startX=e.clientX-container.offsetLeft; //獲取鼠標點與container的相對位置 startY=e.clientY-container.offsetTop; flag=true; } container.onmousemove=function(e){ var e= e||window.event; var endX=e.clientX; var endY=e.clientY; var moveX=endX-startX; var moveY=endY-startY; //范圍限定 var maxW=oMask.offsetWidth-container.offsetWidth; var maxH=oMask.offsetHeight-container.offsetHeight; moveX=Math.min(maxW,Math.max(0,moveX)); //取得范圍在[0,maxW]之間的值 moveY=Math.min(maxH,Math.max(0,moveY)); if(flag==true){ container.style.left=moveX+'px'; //鼠標與可視區域的相對位置-鼠標點與container的相對位置=container與可視區域的相對位置 container.style.top =moveY+'px'; } } document.onmouseup=function(e){ flag=false; } }
jQury實現

$(function(){ var flag=false; var mouseLeft; var mouseTop; $('#top').mousedown(function(event){ var downX=event.pageX; //獲取鼠標坐標 var downY=event.pageY; var offsetLeft=$('#container').position().left //獲取彈出框的left值 var offsetTop =$('#container').position().top mouseLeft=downX-offsetLeft; //計算鼠標在彈出框中的位置 mouseTop =downY-offsetTop; //console.log(mouseLeft) flag=true; }) $(document).mousemove(function(event){ if(flag==true){ var moveX=event.pageX; //獲取鼠標坐標 var moveY=event.pageY; var moveLeft=moveX-mouseLeft; //獲取移動過程中彈出框的left值 var moveTop =moveY-mouseTop; var maxX=$(document).width() -$('#container').outerWidth(); var maxY=$(document).height()-$('#container').outerHeight(); console.log($('#container').outerWidth()) //范圍限定 moveLeft=Math.min(Math.max(0,moveLeft),maxX); moveTop =Math.min(Math.max(0,moveTop),maxY); //console.log(moveLeft) $('#container').css({'left':moveLeft,'top':moveTop,'backgroud':'red'}); } }) $(document).mouseup(function(event){ flag=false; })