2016-02-27 3 views
2

Итак, у меня есть список групп, которые я хочу организовать в рабочем состоянии, например, так:HTML5 Draggable List - несколько 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' было заменено.

Я много искал, но не нашел ничего, что может показать мне, как setData по нескольким значениям, любая помощь, которую очень ценят.

ответ

1

Вы можете запросить свойство обоих предметов и получить доступ к значению 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

Вы приветственные Кева :) – 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

Смежные вопросы