2011-07-16 2 views
0

Я пытаюсь создать функцию перетаскивания в HTML5, где я могу перетаскивать из одного списка в другой. У меня есть один список с перетаскиваемыми элементами и еще один список с элементами, которые добавили события капли. Проблема заключается в том, что независимо от того, на каком элементе я нахожусь, последнее добавленное событие капли - это тот, который вызывается.Несколько событий drop в HTML5

Спасибо за любую помощь или предложения.

Я включил мой код ниже:

<!DOCTYPE html> 

<head> 
<title>List Conversion Test</title> 

<style type="text/css"> 

#list, #cart { 
    display: inline; 
    float: left; 
    border: 1px solid #444; 
    margin: 25px; 
    padding: 10px; 
} 

#list p { 
    background-color: #036; 
    color: #fff; 
} 
#cart p { 
    background-color: #363; 
    color: #fff; 
} 

.listitem { 

} 

.listitem_done { 
    text-decoration: line-through; 
} 

.product { 
    background-color: #CCC; 
} 

.product_over { 
    background-color: #363; 
} 

</style> 


<script type="text/javascript" src="http://html5demos.com/js/h5utils.js"></script> 

</head> 

<body> 

<article> 
    <div id="list"> 
    <p>On My List</p> 
    <ul> 
     <li class="listitem" id="L001">Shopping List Item #1</li> 
     <li class="listitem" id="L002">Shopping List Item #2</li> 
    </ul> 
    <div id="done"> 
     <p>In My Cart</p> 
     <ul></ul> 
    </div> 
    </div> 

    <div id="cart"> 
    <p>Cart</p> 
    <ul> 
     <li class="product" id="P001">Product #1</li> 
     <li class="product" id="P002">Product #2</li> 
    </ul> 
    </div> 

</article> 
<script> 

    // make list items draggable 
    var list = document.querySelectorAll('li.listitem'), thisItem = null; 
    for (var i = 0; i < list.length; i++) { 
    thisItem = list[i]; 

    thisItem.setAttribute('draggable', 'true'); 

    addEvent(thisItem, 'dragstart', function (e) { 
     e.dataTransfer.effectAllowed = 'copy'; 
     e.dataTransfer.setData('Text', this.id); 
    }); 
    } 


    // give products drop events 
    var products = document.querySelectorAll('li.product'), thisProduct = null; 
    for (var i = 0; i < products.length; i++) { 
    thisProduct = products[i]; 

    addEvent(thisProduct, 'dragover', function (e) { 
     if (e.preventDefault) e.preventDefault(); 
     this.className = 'product_over'; 
     e.dataTransfer.dropEffect = 'copy'; 
     return false; 
    }); 

    addEvent(thisProduct, 'dragleave', function() { 
    this.className = 'product'; 
    }); 

    addEvent(thisProduct, 'drop', function (e) { 
     //alert(thisProduct.id); 
     if (e.stopPropagation) e.stopPropagation(); 
     var thisItem = document.getElementById(e.dataTransfer.getData('Text')); 
     thisItem.parentNode.removeChild(thisItem); 
     thisProduct.className = 'product'; 
     handleDrop(thisItem, thisProduct); 
     return false; 
    }); 

    } 

    // handle the drop 
    function handleDrop(i, p) { 
    alert(i.id + ' to ' + p.id); 
    var done = document.querySelector('#done > ul'); 
    done.appendChild(i); 
    i.className = 'listitem_done'; 
    } 


</script> 

</body> 
</html> 

ответ

1

Вот почему это часто плохая идея, чтобы определить функции (такие как функции обратного вызова) в пределах цикла. Вы назначаете thisProduct в цикле, но он будет переназначен для следующей итерации цикла. Способ настройки ваших замыканий, каждый обратный вызов привязан к одной и той же переменной thisProduct и будет использовать последнее значение.

Одним из возможных решений является создание нового закрытия, где thisProduct необходима, таких как

(function(thisProduct) { 
    addEvent(thisProduct, 'drop', function (e) { 
     //alert(thisProduct.id); 
     if (e.stopPropagation) e.stopPropagation(); 
     var thisItem = document.getElementById(e.dataTransfer.getData('Text')); 
     thisItem.parentNode.removeChild(thisItem); 
     thisProduct.className = 'product'; 
     handleDrop(thisItem, thisProduct); 
     return false; 
    }); 
}(thisProduct)); 

Это jsFiddle, кажется, работает для меня. См. here для более подробного объяснения.

+0

Спасибо! Тогда имеет смысл, почему последний id всегда появлялся. Ссылка MDN была полезна; Кажется, мне нужно немного узнать о закрытии. – Paul

+0

Без проблем! Рад был помочь :) –

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