2016-02-27 62 views
2

所以,我有樂隊的名單,我想整理成運行的命令,就像這樣:HTML5可拖曳列表 - 多個setData?

<li data-band-id='1' draggable='true' class='band-name'>Metallica</li> 
<li data-band-id='2' draggable='true' class='band-name'>Slayer</li> 
<li data-band-id='3' draggable='true' class='band-name'>Paradise Lost</li> 
<li data-band-id='4' draggable='true' class='band-name'>Gojira</li> 

我希望能夠拖動這些列表項目內的整體改變每個波段佈局名單。到目前爲止,我有以下的JavaScript來做到這一點:

var dragSatMS = null; 
function handleDragStart(e) { 
    //this.style.color = 'green'; 
    dragSatMS = this; 
    e.dataTransfer.effectAllowed = 'move'; 
    e.dataTransfer.setData('text', this.innerHTML); 
} 
function handleDragOver(e) { 
    if (e.preventDefault) { 
     e.preventDefault(); 
    } 
    e.dataTransfer.dropEffect = 'move'; 
    return false; 
} 
function handleDragEnter(e) { 
    this.classList.add('over'); 
} 
function handleDragLeave(e) { 
    this.classList.remove('over'); 
    //this.style.color = '#333'; 
} 
function handleDrop(e) { 
    if (e.stopPropagation) { 
    e.stopPropagation(); 
    } 
    if (dragSatMS != this) { 
    dragSatMS.innerHTML = this.innerHTML; 
    this.innerHTML = e.dataTransfer.getData('text'); 
    } 
    return false; 
} 
function handleDragEnd(e) { 
    [].forEach.call(mssatCols, function (mSatCol) { 
    mSatCol.classList.remove('over'); 
    //mSatCol.style.color = '#333'; 
    }); 
} 
var mssatCols = document.querySelectorAll('#ms-saturday .band-name'); 
[].forEach.call(mssatCols, function(msSatCol) { 
    msSatCol.addEventListener('dragstart', handleDragStart, false); 
    msSatCol.addEventListener('dragenter', handleDragEnter, false); 
    msSatCol.addEventListener('dragover', handleDragOver, false); 
    msSatCol.addEventListener('dragleave', handleDragLeave, false); 
    msSatCol.addEventListener('drop', handleDrop, false); 
    msSatCol.addEventListener('dragend', handleDragEnd, false); 
}); 

此作品完美,我可以通過拖放名單,讓他們適當地改變帶互換的地方而得名。但是,'data-band-id'屬性的值保持原樣。我知道這正是我所擁有的代碼,那就是我的問題。我想修改代碼,以便拖動和刪除樂隊的名稱「data-band-id」屬性的值被交換。

我google了很多,但沒有發現什麼可以告訴我如何setData在多個值,任何幫助非常感激。

回答

1

您可以查詢兩個項目的attributes屬性並訪問data-band-id的值。一旦你有兩個值,你可以打電話setAttribute("name", "value")更新data-band-id。然後,您更新handleDrop方法是:

function handleDrop(e) { 
    if (e.stopPropagation) { 
    e.stopPropagation(); 
    } 
    if (dragSatMS != this) { 
    dragSatMS.innerHTML = this.innerHTML; 
    this.innerHTML = e.dataTransfer.getData('text'); 
    //Get the data-band-id of both items. 
    itemToReplaceAttr = this.attributes["data-band-id"].value; 
    draggedItemAttr = dragSatMS.attributes["data-band-id"].value; 
    //Call "setAttribute" to update the attributes. 
    this.setAttribute("data-band-id", draggedItemAttr); 
    dragSatMS.setAttribute("data-band-id", itemToReplaceAttr); 
    } 
    return false; 
} 

這裏的好措施演示:Fiddle

+0

以下小提琴進一步支持此答案:https://jsfiddle.net/yw07rhcm/ –

+0

非常感謝你:) – Kev

+0

不客氣Kev :) – Yass

0

亞斯答案是解決問題的一種方式。

但我現在將向您介紹另一種方法,即所有我在拖放中看到的教程都謹慎避免 - 我相信拖放API的使用提供了一個理想的場景,其中事件代理應該閃耀 - 但是,直到日期(據我所知),沒有任何受歡迎的教程探索了這種方法。

如果您急於查看我的建議,請參閱this fiddle

因此,您可以將拖動事件的處理委託給項目的父項,ul。而不是交換被拖動的元素的innerHtml與元素的丟棄將發生,交換outerHtml

var draggedItem = null; 
var ul = document.getElementById('ms-saturday'); 

// delegate event handling to the parent of the list items 
ul.addEventListener('dragstart', buffer(handleDragStart), false); 
ul.addEventListener('dragover', buffer(handleDragOver), false); 
ul.addEventListener('drop', buffer(handleDrop), false); 

function handleDragStart(e) { 
    draggedItem = e.target; 
    e.dataTransfer.effectAllowed = 'move'; 

    // dataTransfer is not really required, but I think IE may need it. 
    // Also, not that if you must use dataTransfer API, 
    // IE strongly requires that the mime type must be 'text'. 
    e.dataTransfer.setData('text', this.innerHTML); 
} 

function handleDragOver(e) { 
    if (e.preventDefault) { 
    e.preventDefault(); 
    } 

    e.dataTransfer.dropEffect = 'move'; 

    return false; 
} 

function handleDrop(e) { 
    var tmp; 

    if (e.stopPropagation) { 
    e.stopPropagation(); 
    } 

    if (draggedItem !== e.target) { 
    // swapp outerHtml here 
    tmp = draggedItem.outerHTML; 
    draggedItem.outerHTML = e.target.outerHTML; 
    e.target.outerHTML = tmp;; 
    } 

    return false; 
} 

// this is used to create the handlers so that there won't be 
// a need to repeat 'if (e.target === ul) {...' for as many times 
// as there are handlers needed. 
function buffer(fn) { 

    return function(e) { 

    // ignore drag-and-drop on the parent element itself 
    if (e.target === ul) { 
     return; 
    } 

    fn.call(this, e); 
    }; 
} 

我留下你來完善這個方法以適應你的口味。

+0

感謝您的幫助,我非常感謝。 – Kev