1. 程式人生 > 其它 >html5滑鼠拖動排序及resize實現方案分析及實踐

html5滑鼠拖動排序及resize實現方案分析及實踐

拖放(Drag和 drop)是 HTML5 標準的組成部分。相比之前用jquery-UI等庫實現,更加方便。使用css 設定resize屬性,通過observeResize監聽元素的大小改變。這個也是一個優化。

對列表進行拖動排序,尺寸改變。之前一般會使用jQuery-UI。其通過mousedown、mousemove、mouseup這三個事件來實現頁面元素被滑鼠拖拽的效果。vue-drag-resize vuedraggable等包也大抵如此:https://codepen.io/lujun-zhou/pen/LYybXNx

而HTML5中直接提供了拖放的API,只要通過監聽元素的拖放事件就能實現各種拖放功能。

拖放(Drag和 drop)是 HTML5 標準的組成部分。相比之前用jquery-UI等庫實現,更加方便(省去計座標計算等)。

為了使元素可拖動,必須把 draggable 屬性設定為 true

<divid=testdraggable=true>test</div>[objectObject]

整個拖拽事件觸發的順序如下:dragstart-> drag -> dragenter -> dragover -> dragleave -> drop ->dragend

拖放事件事件詳情

一個元素被拖放,他可能會經過很多個元素上,最終到達想要放置的元素內。這裡,我暫時把被拖放的元素稱為源物件,被經過的元素稱為過程物件,到達的元素稱為目標物件。不同的物件產生不同的拖放事件。

源物件事件:

dragstart:源物件開始拖放,開始移動時事件觸發

drag:源物件拖放過程中,移動被拖拽物件時觸發

dragend:源物件拖放結束,整個拖放操作結束時觸發。

過程物件事件:

dragenter:源物件進入過程物件範圍內,被拖拽物件進入過程物件時被觸發

dragover:源物件在過程物件範圍內移動,被拖拽物件在過程物件內移動時觸發

dragleave:源物件離開過程物件的範圍,被拖拽物件離開目標物件時觸發

目標物件事件:

drop:源物件拖放到目標物件中,目標物件完全接受被拖拽物件時觸發,可理解為在目標物件內鬆手時觸發。

dragenter和dragover事件的預設行為是拒絕接受任何被拖放的元素。因此,我們必須阻止瀏覽器這種預設行為。e.preventDefault();

如果drop接收盒子要想接收到元素,那麼接收的拖動元素dragenter和dragover必須阻止預設行為。

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

在vue專案中:

@dragstart.native="dragStart(index,$event)"
@dragenter.native.prevent="dragenter(index,$event)"
@dragleave.native.prevent
@dragover.native.prevent
@dragend.native="dragend(index,$event)"
@drop.native.prevent="drop(index,$event)"

這樣才會觸發drop

dataTransfer物件

在所有的拖放事件中都提供了一個數據傳輸物件dataTransfer,主要是用於在源物件和目標物件之間傳遞資料

dataTransfer方法

setData(format, data)

設定拖拽事件中要傳遞的資料,format的引數為資料型別,data要存入的資料。例如:event.dataTransfer.setData('text/plain', 'hello world')

存入的資料型別,共有4種:

    • text/plain

    • text/html

    • text/xml

    • text/uri-list

注:如果給定型別的資料不存在,則將其新增到拖動資料儲存的末尾,使得dataTransfer.types列表中的最後一個專案將是新型別。

getData(format)

該方法從dataTransfer物件中讀取資料,引數為在setData方法中指定的資料型別,例如:event.dataTransfer.getData('text/plain')

clearData()

該方法清空dataTransfer物件中儲存的資料,引數可選,為資料型別。若為空,則清空所有資料。

setDragImage(element,x,y)

  • 該方法通過img元素來設定拖放圖示

  • element表示拖拽時滑鼠下面的圖片(通常是image元素,也可以說canvas元素)

  • x、y分別指示相對於圖片的橫向和縱向偏移量,相對應滑鼠指標。

dataTransfer屬性

dropEffect 和 effectAllowed屬性

給指定拖放操作所允許的一個效果,例如:dataTransfer.effectAllowed = "move"。

  1. effectAllowed用來指定當元素被拖放式所允許的視覺效果。如果effectAllowed屬性是定為none,則不允許拖放元素

  2. dropEffect 表示拖放操作的視覺效果,如果dropEffect 屬性設定為none,則不允許被拖放到目標元素中。

應該在dragstart事件中設定此屬性,以便為拖動源設定所需的拖動效果。在 dragenter 和dragover 事件處理程式中,該屬性將設定為在dragstart 事件期間分配的任何值,因此,可以使用effectAllowed來確定允許哪個效果。其值如下(dropEffect只有none 、copy、move、link):

none 、copy、move、link,copyMove,linkMove、all、uninitialized

chrome 預設是顯示一個綠色的加號,設定:$event.dataTransfer.effectAllowed = 'move'。則恢復成預設滑鼠樣式。

files屬性

返回被拖拽的檔案列表,是一個FileList物件,有length屬性,可通過下標訪問。此功能可用於將檔案從使用者桌面拖動到瀏覽器。一般配合FileReader來處理檔案。如FileReader.readAsDataURL與FileReader.onload

拖動元素排序實現

之前寫了兩篇文章,有讀者留言希望看程式碼,這次大致寫了下

https://codepen.io/lujun-zhou/pen/KKmNgxv

vue實現

https://codepen.io/lujun-zhou/pen/zYwozMZ

magicBox tab 排序也是,就是採用這個

畫布元素位置與尺寸調整

可以先回顧下《再談BOM和DOM(6):dom物件及event物件位值計算—如offsetX/Top,clentX

如果使用mouse事件控制,就顯得非常複雜。這種一般都是使用第三方庫實現,如interact.js 、vue-drag-resize等。

如果直接使用 css resize,然後通過 resizeObserve 回撥尺寸改變,實現起來就變得簡單的多。

這種思路之前也介紹過,如《懶載入優化:JavaScript IntersectionObserver API監聽元素是否可見》。

這裡的大致實現程式碼:

https://codepen.io/lujun-zhou/pen/jOmVLGy

之前做過一版類似DataV的需求,就是直接用html5 原生屬性寫的。

canvas 畫布實現:https://codepen.io/atindo23/pen/OJLbdrJ

滑鼠縮放元素操作

縮放事件,實現不肖多說,MDN案列寫的夠好了

https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onwheel

參考文章:

HTML5--拖放事件與dataTransfer物件https://blog.csdn.net/hjc256/article/details/89021483

說說 HTML 中的dropEffect 和 effectAllowedhttps://blog.csdn.net/gggg5643/article/details/52135824

HTML5 進階系列:拖放 API 實現拖放排序 - 林鑫的文章 - 知乎https://zhuanlan.zhihu.com/p/26666141

HTML5前端技術教程:H5拖放 - 方偉景的文章 - 知乎https://zhuanlan.zhihu.com/p/47458212

轉載本站文章《html5滑鼠拖動排序及resize實現方案分析及實踐》,
請註明出處:https://www.zhoulujun.cn/html/webfront/SGML/html5/2016_0124_434.html