淺談js拖拽

本文來自網易雲社區

做者:劉凌陽


前言

本文依據半年前本人的分享《淺談js拖拽》撰寫,算是一篇遲到的文章。 html

 

基本思路

雖然如今關於拖拽的組件庫處處都是,HTML5也把拖放歸入了標準。但考慮到兼容問題,咱們仍是從最古老的方式開始講起。html5

onmousedown:模擬開始拖拽事件。   鼠標按鍵按下即發生  onmousedown  事件。  獲取鼠標位置,獲取被拖拽元素的位置,記錄二者之間的縱橫座標的差值。對  document  元素綁定  onmousemove,onmouseup  事件。   瀏覽器

爲何是對  document  綁定而不是對被拖動的元素綁定呢?原來是若是對被拖動元素綁定的話當鼠標拖動過快時,會致使鼠標與被拖動元素的脫離。   安全

onmousemove:模擬拖拽中事件。  鼠標拖動即發生  onmousemove  事件。  將被拖拽元素的  position  改爲絕對位置,這個能夠經過  left  和  top  改變該元素的位置,從而使得該元素隨着鼠標的拖拽而移動。獲取鼠標位置,將鼠標  x  座標(  e.clientX  )減去第  2  步儲存的橫座標差做爲被拖動元素的  left  值,將鼠標y  座標(  e.clientY  )減去第  2  步儲存的縱座標差做爲被拖動元素的  top  值。實現元素跟隨鼠標拖動的效果。   函數

onmouseup:模擬拖拽結束事件。  鼠標按鍵彈起即發生  onmouseup  事件。能夠回收  onmousemove  和  onmousedown中的  事件和變量,一次拖拽至此結束。url

(  nej  也提供了拖拽的一個簡單案例,位於  util/dragger/  下,代碼就不貼出來了,有興趣的童鞋能夠自行查閱,畢竟看文字實在是過於枯燥了。  )spa


HTML5拖放

有古老的方式天然有潮流的方式,若是你無需考慮兼容性問題的話,筆者強烈建議你使用HTML5提供的拖放API   。若是你還不曾瞭解,提供你一個  簡單的HTML5拖放實例  http://www.w3school.com.cn/tiy/t.asp?f=html5_draganddrop.net

讓咱們一塊兒來看看HTML5拖放相關的一些知識點。orm

7個事件:htm

dragstart  :當用戶開始拖動對象時觸發。

dragenter  :    當鼠標第一次通過目標元素,且有拖動發生時觸發。此事件的監聽者應指明在這個位置上是否容許  drop  ,或者監聽者不執行任何操做,那麼  drop  默認是不容許的。

dragover  :當鼠標通過一個元素時,且有拖動發生時觸發    。

dragleave  :當鼠標離開一個元素,且有拖動在發生時觸發。

drag  :    當對象被拖動,每次移動鼠標時觸發。

drop  :在  drag  操做的最後發生  drop  時,在元素上觸發此事件。監聽者應該負責檢索拖動的數據,並插入  drop  的位置。

dragend  :    在拖動對象時放開鼠標按鍵時觸發。

draggable屬性:

若是網頁元素的draggable元素爲true,這個元素就是能夠拖動的。

<div draggable="true">Draggable Div</div>

dataTransfer對象:

拖動過程當中,回調函數接受的事件參數,有一個dataTransfer屬性。它指向一個對象,包含了與拖動相關的各類信息。

dataTransfer對象的屬性:

  • dropEffect:拖放的操做類型,決定了瀏覽器如何顯示鼠標形狀,可能的值爲copy、move、link和none。

  • effectAllowed:指定所容許的操做,可能的值爲copy、move、link、copyLink、copyMove、linkMove、all、none和uninitialized(默認值,等同於all,即容許一切操做)。

  • files:包含一個FileList對象,表示拖放所涉及的文件,主要用於處理從文件系統拖入瀏覽器的文件。

  • types:儲存在DataTransfer對象的數據的類型。

  • dataTransfer對象的方法:

  • setData(format, data):在dataTransfer對象上儲存數據。第一個參數format用來指定儲存的數據類型,好比text、url、text/html等。

  • getData(format):從dataTransfer對象取出數據。

  • clearData(format):清除dataTransfer對象所儲存的數據。若是指定了format參數,則只清除該格式的數據,不然清除全部數據。

  • setDragImage(imgElement, x, y):指定拖動過程當中顯示的圖像。默認狀況下,許多瀏覽器顯示一個被拖動元素的半透明版本。參數imgElement必須是一個圖像元素,而不是指向圖像的路徑,參數x和y表示圖像相對於鼠標的位置。

dataTransfer對象,   容許在其上存儲數據,這使得在被拖動元素與目標元素之間傳送信息成爲可能。

e.preventDefault():

ondragover有一個默認行爲,那就是當  ondragover觸發時,ondrop會失效!

如何阻止?

ondragover = function(e){e.preventDefault();    ....}

附一張整理好的圖片供你們理解:

             


案例

扯了這麼多,最後再舉個栗子來結束本文。先上圖片...


這是筆者在網易有數項目中的一個需求,實現文件拖拽上傳。

實現步驟:

  1.監聽事件

   

  其中dragenter和dragleave只是處理了外框高亮的效果,如上面圖片所示。

  須要注意的是必定要將dragover的默認事件取消掉,否則沒法觸發drop事件。能夠用preventDefault(),也能夠用nej的_v._$stop(_event)。如需拖拽頁面裏的元素,須要給其添加屬性draggable=」true」。這些上文已經有所說起。

  2.處理drop事件

  在drop事件回調函數中經過_event.dataTransfer.files獲取拖拽文件列表。dataTransfer對象真是個好東西。

  3.發送文件數據

  使用FormData模擬表單數據AJAX提交文件流。

 

  至此,HTML5的文件拖拽上傳就實現了,是否是很easy?

 

網易雲大禮包:https://www.163yun.com/gift

本文來自網易實踐者社區,經做者劉凌陽受權發佈


相關文章:
【推薦】 Innodb實踐總結(一)
【推薦】 網易易盾驗證碼的安全策略
【推薦】 nova狀態同步

相關文章
相關標籤/搜索