最近的一次專案開發中用到了H5的拖曳功能,由於現有專案使用的是VUE全家桶,使用了vuedragable這個插件,但是整個過程是比較痛苦的。遂決定從H5拖曳的原理開始研究,然後再將其應用到數據驅動的框架中。在H5中要實現拖放操作,至少需要經過兩個步驟:1) 將想要拖放的物件元素的draggable屬性設為true(img與a元素預設允許拖放);2) 編寫與拖放相關的事件處理程式碼。為了測試簡便,我這裡先使用jQuery函式庫完成拖曳的基本功能。
1. 拖曳過程1.1 拖曳事件當按住滑鼠拖曳draggable元素的時候會依照以下順序依序觸發
dragstart -> drag -> dragend
當將draggable元素元素拖曳到容器中將會依照以下順序依序觸發
dragenter -> dragover -> drop
dragenter:只要有元素被拖曳到放置目標上,就會觸發dragenter事件
dragover:dragenter緊接在後的是dragover事件,而且在被拖曳的元素還在放置目標的範圍內移動時,就會持續觸發該事件。
dragleave:元素被拖曳了放置目標,會引發dragleave
drop:將拖曳元素放置到目標元素上的時候會激發
1.3 完整事件流從開始拖曳元素到放置元素到目標區域,將會依照以下順序依序觸發
dragstart->drag->dragenter->dragover->dragleave->drop->dragend
2. 解決firefox對拖曳不支援的問題如果我們直接為一個元素添加draggable屬性,在chrome,opera中是可以直接進行拖曳(沒有可以釋放的操作(例如箭頭變+號)),但是在firefox卻沒有反應
<ul class=canDrog> <li draggable=true id=1>優</li> <li draggable=true id=2>良</li> <li draggable=true id=3>中</li> <li draggable=true id=4>差</li> </ul> <script> //沒有任何JS程式碼</script>
要解決這個問題必須為拖曳元素綁定dragstart事件處理函數,並且在該函數中呼叫event.dataTransfer.setData函數
<script> <ul class=canDrog> <li draggable=true id=1>優</li> <li draggable=true id=2>良</li> <li draggable=true id=3>中</li > <li draggable=true id=4>差</li> </ul> $('.canDrog > li').bind('dragstart',function(event){ //firefox必須存取用於拖曳通訊的dataTransfer物件event.dataTransfer.setData(Text,'1'); });</script> 3. 解決chrome,opera拖曳元素到容器中時沒有顯示可釋放標識問題可釋放標識使用不同的作業系統可能不同,在mac chrome中出現的是一個圓形標識裡面嵌入一個白色的'+'。
解決方案是為容器綁定dragover事件
<ul class=canDrog> <li draggable=true id=1>優</li> <li draggable=true id=2>良</li> <li draggable=true id=3>中</li> <li draggable=true id=4>差</li> </ul> <table class=dataTbl> <thead> <tr> <th style=width: 10%>節次/星期</th> <th>週一</th> <th>週二</th> <th>週三</th> <th>週四</th> <th>週五< /th> </tr> </thead> <tbody> <tr> <td>第一節</td> <td draggable=true ></td> <td draggable=true ></td> <td draggable =true ></td> <td draggable=true ></td> <td draggable=true ></td> </tr> <!--此處省略--> </tbody> </table><script> $('.canDrog > li'). bind('dragstart',function(event){ //firefox 必須存取用於拖曳通訊的dataTransfer物件event.dataTransfer.setData(Text,'1'); }); //google chrome,opera需要加$(.dataTbl).bind(dragover,'td',function(e){ e.originalEvent.preventDefault(); }) </script> 4. 解決放置時firefox開啟新分頁問題使用firefox的時候如果釋放了被拖曳的元素,預設瀏覽器將會開啟一個新的選項卡,如下
這是由於drop回呼函數之後瀏覽器執行了預設行為,通常的解決方案在拖曳容器的drop鉤子中添加阻止預設事件執行以及阻止冒泡的程式碼。
<script> //將元素釋放到目前元素中$('.dataTbl').bind('drop','td',function(event){ console.log('+++drop'); event.preventDefault (); event.stopPropagation(); });</script>但是如果將draggable元素拖曳到其他地方,依然會導致開啟新分頁問題的出現,這時可以為所有容器添加如上程式碼。
5. 寫一個完整小例子原始碼: https://github.com/pluslicy/drag
隨後將對vuedraggable外掛程式庫進行學習,應用在vue框架中
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。