UI組件之浮出層的拖拽
上次總結了一下簡單的浮出層的設計,不了解的可以猛戳下面這條鏈接:
UI組件之浮出層
這次的這篇總結主要是參考的這篇文章:js拖拽事件實例,不過自己多做了一點分析
這次來總結一下浮出層的拖拽,期間遇到了一些小問題,不過最後也解決了,這裏也總結一下。
首先,我們要實現的效果是浮出層在鼠標點擊之後隨著鼠標移動,松開之後停止移動,並且邊框不得超出邊界。
網上很多教程已經說得很清楚了,這裏就再啰嗦兩句,這個過程總共分為三步:
- 鼠標點下之時用onmousedown事件記錄鼠標點下時與浮出層的相對位置
- 用onmousemove事件讓浮出層跟隨鼠標移動,每當用戶將鼠標移動一個像素,就會發生一個 mousemove 事件,我們在這個事件中改變浮出層的位置即可
- 用onmouseup事件在鼠標松開時清除onmousemove中的事件
還需要一些額外的知識,是關於offsetWidth,offsetLeft等等,在網上找到一篇文章不錯(圖畫的比較清楚),鏈接如下:
關於offsetWidth、offsetLeft等概念的理解
接下來是代碼實現:
1、計算鼠標與浮出層的相對位置
horizen.onmousedown=function(ev) //鼠標按下浮出層 { var oEvent=ev||event;//這裏是為了瀏覽器兼容,大家可以上網去查一下
disX=oEvent.clientX-horizen.offsetLeft; /*鼠標的X坐標減去浮出層的左邊距就等於disX, 這個disX是用於確定鼠標移動浮出層時鼠標點和浮出層之間的左面距離,
這個距離是不會變的,通過這個新鼠標的X坐標減去disX就是浮出層的Left*/ disY=oEvent.clientY-horizen.offsetTop;
……
……
}
- 其中的clientX是鼠標相對於整個屏幕在X軸上的位置,clientY是鼠標相對於整個屏幕在Y軸上的位置
2、根據鼠標的移動計算出浮出層的offsetLeft應有的距離,從而改變浮出層的位置,並根據此距離判斷浮出層是否超出邊界
horizen.onmousedown=function(ev) { var oEvent=ev||event; disX=oEvent.clientX-horizen.offsetLeft; disY=oEvent.clientY-horizen.offsetTop; document.onmousemove=function(ev) { var oEvent=ev||event; //此處是為了瀏覽器兼容,大家可以上網去查一下 var oLeft=oEvent.clientX-disX; //新鼠標X坐標減去disX,也就是鼠標移動浮出層後的Left var oTop=oEvent.clientY-disY; if(oLeft<0) //浮出層的Left小於0,也就是移出了左邊 { oLeft=0; //就把浮出層的Left設置為0,就不能移出左邊 } else if(oLeft>document.documentElement.clientWidth-horizen.offsetWidth) //屏幕寬度減去浮出層的寬度就得出了浮出層到達最右邊的寬度 { oLeft=document.documentElement.clientWidth-horizen.offsetWidth; //如果Left大於這個像素,就把Left設置為這個像素 } if(oTop<0) { oTop=0; } else if(oTop>document.documentElement.clientHeight-horizen.offsetHeight) { oTop=document.documentElement.clientHeight-horizen.offsetHeight; } console.log(oLeft); horizen.style.left=oLeft+‘px‘; //浮出層的Left設置為新鼠標X坐標減去disX的值 horizen.style.top=oTop+‘px‘; }; return false; //阻止FireFox的默認事件 bug,(額……不太理解,有大神知道希望賜教) }
- 以上註釋只寫了左右的,上下的是一樣的
3.鼠標松開時清除onmousemove中的事件
document.onmouseup=function() //鼠標松開時 { document.onmousemove=null; //把鼠標移動清除 };
這樣我們的浮出層的拖拽就做好了……
一切看似如此完美,可是當我打開瀏覽器調試的時候卻發現,浮出層左邊拖拽時會超出邊界,右邊會到達不了邊界,上下也是這樣
瀏覽器也並沒有報錯,檢查了代碼也沒有錯誤,最後打了個斷點調試了一下,發現在計算鼠標相對位置時,disX(只討論x軸上的)的值比較小,究其原因是因為offsetLeft過大,上網查了一下以後發現,原來是translate的原因,元素利用translate移動後不會影響offsetLeft的值,意思就是它是按我向左移動前的那個浮出層計算offsetLeft的,那麽offset的值自然就會變大了,並且其變大的值就是我向左移動的值(浮出層的width是400px;我想左移動了自身的50%也就是200px),所以我們需要對判定的條件進行一些修改:
if(oLeft<200) //移動前浮出層的Left小於200,也就是移出左邊 { oLeft=0; //就把浮出層的Left設置為200,就不能移出左邊 } else if(oLeft>document.documentElement.clientWidth-horizen.offsetWidth+200) //屏幕寬度減去DIV的寬度就得出了浮出層到達最右邊的寬度, { oLeft=document.documentElement.clientWidth-horizen.offsetWidth+200; //如果Left大於這個值就把Left設置為這個值 }
上下也根據浮出層的高度改一下就可以了
這樣我們的浮出層拖拽的效果就真的做好了~
UI組件之浮出層的拖拽