HTML5拖放排序

最近在項目中遇到了拖動排序的需求,因此就學習了一下H5的新屬性,寫篇博客記錄一下。html

draggable屬性是指定當前元素能夠被拖動的屬性;咱們要爲須要拖動的元素設置該屬性
<div id="columns">
  <div class="column" draggable="true"><header>A</header></div>
  <div class="column" draggable="true"><header>B</header></div>
  <div class="column" draggable="true"><header>C</header></div>
</div>
<style>
/* Prevent the text contents of draggable elements from being selectable. */
[draggable] {
  -moz-user-select: none;
  -khtml-user-select: none;
  -webkit-user-select: none;
  user-select: none;
  /* Required to make elements draggable in old WebKit */
  -khtml-user-drag: element;
  -webkit-user-drag: element;
}
.column {
  height: 150px;
  width: 150px;
  float: left;
  border: 2px solid #666666;
  background-color: #ccc;
  margin-right: 5px;
  -webkit-border-radius: 10px;
  -ms-border-radius: 10px;
  -moz-border-radius: 10px;
  border-radius: 10px;
  -webkit-box-shadow: inset 0 0 3px #000;
  -ms-box-shadow: inset 0 0 3px #000;
  box-shadow: inset 0 0 3px #000;
  text-align: center;
  cursor: move;
}
.column header {
  color: #fff;
  text-shadow: #000 0 1px;
  box-shadow: 5px;
  padding: 5px;
  background: -moz-linear-gradient(left center, rgb(0,0,0), rgb(79,79,79), rgb(21,21,21));
  background: -webkit-gradient(linear, left top, right top,
                               color-stop(0, rgb(0,0,0)),
                               color-stop(0.50, rgb(79,79,79)),
                               color-stop(1, rgb(21,21,21)));
  background: -webkit-linear-gradient(left center, rgb(0,0,0), rgb(79,79,79), rgb(21,21,21));
  background: -ms-linear-gradient(left center, rgb(0,0,0), rgb(79,79,79), rgb(21,21,21));
  border-bottom: 1px solid #ddd;
  -webkit-border-top-left-radius: 10px;
  -moz-border-radius-topleft: 10px;
  -ms-border-radius-topleft: 10px;
  border-top-left-radius: 10px;
  -webkit-border-top-right-radius: 10px;
  -ms-border-top-right-radius: 10px;
  -moz-border-radius-topright: 10px;
  border-top-right-radius: 10px;
}

.ghost{
  optcity:0.6;
}

</style>

監聽拖動事件

  • dragstart   //當用戶開始拖動一個元素或者一個選擇文本的時候 dragstart 事件就會觸發。
  • drag      //當元素或者選擇的文本被拖動時觸發 drag 事件 (每幾百毫秒)
  • dragenter   //當拖動的元素或被選擇的文本進入有效的放置目標時, dragenter 事件被觸發。
  • dragleave   //當一個被拖動的元素或者被選擇的文本離開一個有效的拖放目標時,將會觸發dragleave 事件
  • dragover    //當元素或者選擇的文本被拖拽到一個有效的放置目標上時,觸發 dragover 事件(每幾百毫秒觸發一次)。
  • drop       //當一個元素或是選中的文字被拖拽釋放到一個有效的釋放目標位置時,drop 事件被拋出。
  • dragend    //拖放事件在拖放操做結束時觸發(經過釋放鼠標按鈕或單擊escape鍵)

咱們須要如下概念:源元素(拖動的起源點)、數據有效負載(咱們嘗試拖放的內容)和目標(接納拖放內容的區域)。源元素能夠是圖片、列表、連接、文件對象、HTML 內容等。目標是接納用戶嘗試放置的數據的放置區(或放置區組)。請注意,並不是全部元素均可以做爲目標(例如圖片)。html5

dataTransfer

dataTransfer是用於元素拖動時控制拖動的類型和數據交換的,主要有如下屬性:node

  •   dragEffect             獲取 / 設置實際的放置效果,它應該始終設置成 effectAllowed  的可能值之一;拖動時鼠標顯示的效果,根據本身的功能來設定 
    • copy: 複製到新的位置
    • move: 移動到新的位置.
    • link: 創建一個源位置到新位置的連接.
    • none: 禁止放置(禁止任何操做).
  •   effectAllowed        用來指定拖動時被容許的效果
  • 可能的值:git

    • copy: 複製到新的位置.
    • move:移動到新的位置 .
    • link:創建一個源位置到新位置的連接.
    • copyLink: 容許複製或者連接.
    • copyMove: 容許複製或者移動.
    • linkMove: 容許連接或者移動.
    • all: 容許全部的操做.
    • none: 禁止全部操做.
    • uninitialized: 缺省值(默認值), 至關於 all.
  •   files                       包含一個在數據傳輸上全部可用的本地文件列表

方法:github

  • clearData()          刪除與給定類型關聯的數據。類型參數是可選的。若是類型爲空或未指定,將刪除全部類型相關聯的數據。若是不存在指定類型的數據,或數據傳輸不包含任何數據,此方法將沒有任何效果。
  • obj.clearData(type);
  • getData()             根據指定的類型檢索數據,若是指定類型的數據不存在或者該 DataTransfer 對象中沒有數據,方法將返回一個空字符串。
  • obj.getData(type);
  • setData()             爲一個給定的類型設置數據。若是該數據類型不存在,它將添加到的末尾,這樣類型列表中的最後一個項目將是新的格式。若是已經存在的數據類型,替換相同的位置的現有數據。就是,當更換相同類型的數據時,不會更改類型列表的順序。
  • obj.setData(type,data);
  • setDragImage()   自定義一個指望的拖動時的圖片。大多數狀況下,這項不用設置,由於被拖動的節點被建立成默認圖片。
  • obj.setDragImage(imgElement,offsetX,offsetY);    offsetX,offsetY爲圖片與鼠標的偏移量
function sortable(rootEl, onUpdate) {
    var dragEl;
    
    // 將全部的子類元素設置爲可拖動的  draggable = true
    [].slice.call(rootEl.children).forEach(function (itemEl) {
        itemEl.draggable = true;
    });
    
    // 該函數負責進行排序
    function _onDragOver(evt) {
        evt.preventDefault();
        evt.dataTransfer.dropEffect = 'move';
       
        var target = evt.target;
        if (target && target !== dragEl && target.nodeName == 'LI') {
            // Sorting
            rootEl.insertBefore(dragEl, target.nextSibling || target);
        }
    }
    
    // 排序結束後的鉤子函數
    function _onDragEnd(evt){
        evt.preventDefault();
       
        dragEl.classList.remove('ghost');
        rootEl.removeEventListener('dragover', _onDragOver, false);
        rootEl.removeEventListener('dragend', _onDragEnd, false);

        onUpdate(dragEl);
    }
    
    // 開始排序  監聽父元素的dragstart 事件
    rootEl.addEventListener('dragstart', function (evt){
        // 保存當前被拖動的子元素
        dragEl = evt.target; 
        
        // 設置移動的類型
        evt.dataTransfer.effectAllowed = 'move';
        // 設置要移動的數據
        evt.dataTransfer.setData('Text', dragEl.textContent);
        // 監聽元素的dragover dragend 事件
        rootEl.addEventListener('dragover', _onDragOver, false);
        rootEl.addEventListener('dragend', _onDragEnd, false);
 
        //這裏若是不添加setTimeout拖出去的元素也會添加上該類名  
        setTimeout(function () {
            dragEl.classList.add('ghost');
        }, 0)
    }, false);
 }
                        
 // Using                    
 sortable(document.getElementById('columns'), function (item) {
    console.log(item);
 });

 參考文章:1.Sorting with the help of HTML5 Drag'n'Drop APIweb

                   2.Native HTML5 Drag and Drop函數

相關文章
相關標籤/搜索