摘要:原生實現對元素的拖拽一背景介紹此處為鋪墊內容,可跳過隨著前端的不斷發展,各種各樣的前端規范和新知識新技術層出不窮,極大地拓展了開發者的操作空間,也大大地提升了用戶體驗。
原生 JS 實現對 html 元素的拖拽 一、背景介紹
【此處為鋪墊內容,可跳過】 隨著 Web 前端的不斷發展,各種各樣的前端規范和新知識、新技術層出不窮,極大地拓展了開發者的操作空間,也大大地提升了用戶體驗。而隨著移動端的不斷發展,在移動端,人機交互方式發生了很大轉變,新的人機交互方式對提供給用戶的 “動作” 有了更高要求,例如拖拽功能,就是在移動端會經常接觸到的功能。此文就詳細地講解一下,一個簡單的拖拽功能的實現(拖拽元素可改變,瀏覽器窗口邊界檢測)。
二、知識準備為了讓各位對此文內容有更深刻的掌握,需要掌握如下知識。
1、clientX,clientY 屬性
clientX( clientY ) 事件屬性返回當事件被觸發時鼠標指針相對于瀏覽器當前可視窗口的水平(垂直)坐標。
注意:不包括工具欄和滾動條
2、offsetTop,offsetLeft 屬性
offsetTop ( offsetLeft ),指的是子元素距離其父元素的上邊框(左邊框)的偏移量,在不同的瀏覽器中其值不同,且與父元素的 position 屬性( position: static; 除外)有關。在不同瀏覽以及不同 position 下的具體值,讀者可以自行查閱相關資料,因其內容較多,就不展開論述了。
3、clientWidth,clientHeight屬性
Element.clientWidth( Element.clientHeight )屬性表示元素的內部寬度,以像素計。該屬性包括內邊距,但不包括垂直滾動條(如果有)、邊框和外邊距。該屬性值會被四舍五入為一個整數。如果你需要一個小數值,可使用 element.getBoundingClientRect() 。
4、setCapture,releaseCapture 方法
三、實現思路MDN 對 SetCapture() 函數的說明為:“該函數在屬于當前線程的指定窗口里設置鼠標捕獲。一旦窗口捕獲了 鼠標,所有鼠標輸入都針對該窗口,無論光標是否在窗口的邊界內。同一時刻只能有一個窗口捕獲鼠標。如果鼠標光標在另一個線程創建的窗口上,只有當鼠標鍵按下時系統才將鼠標輸入指向指定的窗口。”
通俗來講,舉個栗子:一只羊被一根有彈性的繩子( SetCapture )拴在木樁,羊可以在繩子可以延展的范圍內 隨意活動,但永遠無法擺脫繩子的束縛。除非有其他因素導致繩子斷了(使用了 ReleaseCapture 或點擊了其他窗口)。
ReleaseCapture() 用來釋放鼠標捕獲,當不再需要繼續獲得鼠標消息就要應該調用 ReleaseCapture() 釋放掉,否則別的線程想捕獲鼠標事件就會失敗。注意:SetCapture() 和 ReleaseCapture() 必須成對出現。
如果想對元素進行拖拽,那么必須使用三個事件,并且這三個事件的使用順序不能打亂。
1、onmousedown:鼠標按下事件 2、onmousemove:鼠標移動事件 3、onmouseup:鼠標抬起事件
拖拽的基本原理就是根據鼠標的移動來移動被拖拽的元素。鼠標的移動也就是 x、y 坐標的變化;元素的移動就是元素 position 屬性的 top 和 left 值的改變。當然,并不是任何時候移動鼠標都要造成元素的移動,而應該判斷鼠標左鍵的狀態是否為按下狀態,是否是在可拖拽的元素上按下的。具體過程如下:
拖拽狀態?=?false 鼠標在元素上按下之后 { 拖拽狀態?=?true 設置鼠標捕獲 記錄下鼠標的 x,y 坐標 記錄下元素的 x,y 坐標 } 鼠標在元素上移動時 { 若拖拽狀態為 false 就什么也不做 如果拖拽狀態是 true,那么 元素的 y?坐標 =?現在鼠標 y?-?原來鼠標 y?+?原來元素 y 元素的 x?坐標 =?現在鼠標 x?-?原來鼠標 x?+?原來元素 x } 鼠標抬起時 { 拖拽狀態?=?false }四、完整源碼
原生JS實現元素拖拽
五、案例總結注意事項
1、onmousedown 事件中的操作對象為拖拽元素,而 onmousemove 和 onmouseup 事件中的操作對象為 document,這是因為,點擊某物體時,用需要拖拽的對象即可,onmousemove 和 onmouseup 是全局區域,也就是整個文檔通用,應該使用 document 對象而不是被拖拽的對象(否則,采用拖拽對象時物體只能往右方或下方移動)2、之所以使用 setCapture() 和 releaseCapture(),其目的是為了修復低版本 IE 的 bug。在低版本 IE 下,當我們在要拖動的元素上,按下鼠標按鈕拖動時,當拖動過快,或者是超出瀏覽器的文檔窗口時,拖動對象身上的 onmousedown 事件就會失效。在 Chrome 我們可以為 doucment 綁定 onmouseout 事件來判斷是否發生這樣的情況,但是 IE 下卻行不通,所以最好的解決辦法就時為要拖動的元素對象鎖定鼠標事件,在拖動后再解除事件鎖定。在本例中,這兩個方法用于 onmousedown 和 onmouseup 中。
3、另外,在 Firefox 中有相似的功能,它們分別是:
captureEvents ( Event.eventType )
releaseEvents ( Event.eventType )
雖然元素的拖拽算是一個比較基礎的知識點,但在實現的過程中,有許多細節需要注意,例如計算坐標的時候,對那幾個屬性的了解程度,再例如,事件的觸發順序,還有,IE 中的事件獲取, setCapture() 和 releaseCapture() 等。
雖然 H5 直接提供了拖拽 API,但為了兼容性,小伙伴們還是需要用 js 去處理的。上例中,雖然對拖拽做了一定的兼容性處理和封裝,拖拽對象可以是 div,圖片,文字等,但總的來說,是一個比較基礎的實現,但有了這個原型,小伙伴們可以根據自己的需求,再加以封裝和拓展,例如限定拖拽方向、范圍、速度等等。有任何疑問或建議,可以在評論區留言哦,轉載請注明出處。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/54106.html
摘要:原生實現對元素的拖拽一背景介紹此處為鋪墊內容,可跳過隨著前端的不斷發展,各種各樣的前端規范和新知識新技術層出不窮,極大地拓展了開發者的操作空間,也大大地提升了用戶體驗。 原生 JS 實現對 html 元素的拖拽 一、背景介紹 【此處為鋪墊內容,可跳過】 隨著 Web 前端的不斷發展,各種各樣的前端規范和新知識、新技術層出不窮,極大地拓展了開發者的操作空間,也大大地提升了用戶體驗。而隨著...
摘要:前面幾篇文章,我跟大家分享了的一些基礎知識,這篇文章,將會進入第一個實戰環節利用前面幾章的所涉及到的知識,封裝一個拖拽對象。不封裝對象直接實現利用原生封裝拖拽對象通過擴展來實現拖拽對象。 showImg(https://segmentfault.com/img/remote/1460000008699587); 前面幾篇文章,我跟大家分享了JavaScript的一些基礎知識,這篇文章,...
摘要:涉及部分的,不會對理解全局產生干擾。在上監聽事件,當為畫布時,通過創建一個藍色虛線框移動的時候,更新的位置在上監聽事件,落在畫布時,創建一個的節點從而完成整個拖拽添加元素的功能。 showImg(https://segmentfault.com/img/remote/1460000019564977);showImg(https://segmentfault.com/img/remot...
摘要:涉及部分的,不會對理解全局產生干擾。在上監聽事件,當為畫布時,通過創建一個藍色虛線框移動的時候,更新的位置在上監聽事件,落在畫布時,創建一個的節點從而完成整個拖拽添加元素的功能。 showImg(https://segmentfault.com/img/remote/1460000019564977);showImg(https://segmentfault.com/img/remot...
閱讀 455·2023-04-25 23:00
閱讀 3486·2021-11-22 13:54
閱讀 1886·2021-10-27 14:14
閱讀 1478·2019-08-30 13:59
閱讀 3503·2019-08-23 16:15
閱讀 1948·2019-08-23 16:06
閱讀 3315·2019-08-23 15:26
閱讀 1246·2019-08-23 13:48