2017-05-04 27 views
8

我很難用文字來總結這個錯誤。所以我爲這個bug做了video。 基本上,當dragEnd被調用時,元素就好像要去原來的地方一樣動畫。如何停止默認行爲?我也爲此做了fiddlecodepen如何在拖放時停止dragend的默認行爲?

我有兩個我的例子列表,當釋放鼠標按鈕後調用dragEnd。來自一個列表的元素將動畫轉到其原始位置的列表,而不是它將要放置的位置。

JS代碼:

'use strict'; 

var source = null; var heightWidth = null; var lastDragOverElementId = null; var dragImageSource = null; 

function listItemDragStartHandler(event) { 
    source = event.currentTarget; 
    heightWidth = []; 
    heightWidth.push(source.offsetHeight); 
    heightWidth.push(source.offsetWidth); 
    event.dataTransfer.setData('text/html', event.currentTarget.innerHTML); 
    event.dataTransfer.effectAllowed = 'move'; 
    // Drag image logic 
    dragImageSource = source.cloneNode(true); 
    dragImageSource.style.position = 'absolute'; 
    // Don't show the element 
    dragImageSource.style.top = '0px'; 
    dragImageSource.style.left = '-' + String(window.innerWidth) + 'px'; 
    // dragImageSource.style.left = '-100px'; 
    var toTiltElement = dragImageSource.getElementsByClassName('item-list-element')[0]; 
    toTiltElement.style.transform = 'rotate(5deg)'; 
    document.body.append(dragImageSource); 
    event.dataTransfer.setDragImage(dragImageSource, heightWidth[1]/2, heightWidth[0]/2); } 

function dragoverHandler(event) { 
    event.preventDefault(); 
    event.dataTransfer.dropEffect = 'move'; 
    source.style.display = 'none'; 
    var currentElement = event.currentTarget; 
    var listContainer = currentElement.parentNode; 
    if (lastDragOverElementId != currentElement.getAttribute('id')) { 
     lastDragOverElementId = currentElement.getAttribute('id'); 
     if(document.getElementById('grayed-empty-node') !== null) { 
      if(currentElement.getAttribute('id') !== 'grayed-empty-node') { 
       document.getElementById('grayed-empty-node').remove(); 
      } 
     } 
     var isGrayEmptyNodeThere = document.getElementById('grayed-empty-node'); // 
     if(isGrayEmptyNodeThere === null) { 
      var emptyNode = document.getElementById('empty-node').cloneNode(true); 
      emptyNode.removeAttribute('id'); 
      emptyNode.setAttribute('id', 'grayed-empty-node'); 
      emptyNode.setAttribute('class', 'fade-in'); 
      emptyNode.style.height = String(heightWidth[0]) + 'px'; 
      emptyNode.style.width = String(heightWidth[1]) + 'px'; 
      listContainer.insertBefore(emptyNode, currentElement); 
     } 
    } } 

function dragLeaveHandler(event) { 
    event.preventDefault(); 
    var currentElement = event.currentTarget; 
    var listContainer = currentElement.parentNode; 
    var elementList = listContainer.getElementsByClassName('item-template-container'); 
    var visibleElementList = []; 
    var i = 0; 
    for (i=0; i<elementList.length; i++) { 
     if (elementList[i].style.display !== 'none') { 
      visibleElementList.push(elementList[i]); 
     } 
    } 
    // Last element ondragleave handler should be delayed, otherwise it 
    // would spin off chain reaction. 
    var lastVisibleElement = visibleElementList[visibleElementList.length - 1]; 
    // Basically last element 
    if (currentElement.id === lastVisibleElement.getAttribute('id')) { 
     lastVisibleElement.removeAttribute('ondragleave'); 
     if(document.getElementById('grayed-empty-node') !== null) { 
      document.getElementById('grayed-empty-node').remove(); 
     } 
     var isGrayEmptyNodeThere = document.getElementById('grayed-empty-node'); 
     if(isGrayEmptyNodeThere === null) { 
      var listContainer = currentElement.parentNode; 
      var emptyNode = document.getElementById('empty-node').cloneNode(true); 
      emptyNode.removeAttribute('id'); 
      emptyNode.setAttribute('id', 'grayed-empty-node'); 
      emptyNode.setAttribute('class', 'fade-in'); 
      emptyNode.style.height = String(heightWidth[0]) + 'px'; 
      emptyNode.style.width = String(heightWidth[1]) + 'px'; 
      listContainer.insertBefore(emptyNode, null); 
     } 
     // This delayed the chain reaction 
     setTimeout(function() { 
      visibleElementList[visibleElementList.length - 1].setAttribute('ondragleave', 'dragLeaveHandler(event);'); 
     }, 500); 
    // When event is on last element set the lastDragOverElementId to null 
    // then dragover to lastVisibleElement(second last element) can be handled 
    // otherwise dragover to second last element won't show placeholder. 
    lastDragOverElementId = null; 
    } } 

function dragEndHandler(event) { 
    event.preventDefault(); 
    // Check the dropEffect 
    dragImageSource.remove(); 
    var listElement = document.getElementById('grayed-empty-node') 
    var listContainer = listElement.parentNode; 
    if (event.dataTransfer.dropEffect === 'none') { 
     var grayEmptyNode = document.getElementById('grayed-empty-node'); 
     // When grayEmptyNode is null, that will append at the end. 
     listContainer.insertBefore(source, grayEmptyNode); 
     source.style.display = ''; 
     if(document.getElementById('grayed-empty-node') !== null) { 
      document.getElementById('grayed-empty-node').remove(); 
     } 
    } else if (event.dataTransfer.dropEffect === 'move') { 
     var grayEmptyNode = document.getElementById('grayed-empty-node'); 
     // When grayEmptyNode is null, that will append at the end. 
     listContainer.insertBefore(source, grayEmptyNode); 
     source.style.display = ''; 
     if(document.getElementById('grayed-empty-node') !== null) { 
      document.getElementById('grayed-empty-node').remove(); 
     } 
    } } 

function delete_item(event) { 
    var currentElement = event.currentTarget; 
    var grandParentOfDelete = currentElement.parentNode.parentNode; 
    grandParentOfDelete.remove(); } 

function add_item() { 
    var item_text_node = document.getElementsByName('add-item-text')[0] 
    var item_text = item_text_node.value; 
    if (item_text.length > 0) { 
     var item_template = document.getElementById('item-template-container'); 
     var item_clone = item_template.cloneNode(true); 
     item_clone.removeAttribute('id'); 
     var random_id = (new Date().getTime() + 
      parseInt(Math.random(0, 1000) * 1000)) 
     item_clone.setAttribute('id', random_id); 
     var clone_text = item_clone.getElementsByClassName('item-text')[0]; 
     clone_text.textContent = item_text; 
     // reset the value 
     item_text_node.value = ''; 
     var item_list = document.getElementById('item-list'); 
     item_list.appendChild(item_clone); 
    } else { 
     alert('No text?? Add some text!'); 
    } } 

function add_item_2() { 
    var item_text_node = document.getElementsByName('add-item-text-2')[0] 
    var item_text = item_text_node.value; 
    if (item_text.length > 0) { 
     var item_template = document.getElementById('item-template-container'); 
     var item_clone = item_template.cloneNode(true); 
     item_clone.removeAttribute('id'); 
     var random_id = (new Date().getTime() + 
      parseInt(Math.random(0, 1000) * 1000)) 
     item_clone.setAttribute('id', random_id); 
     var clone_text = item_clone.getElementsByClassName('item-text')[0]; 
     clone_text.textContent = item_text; 
     // reset the value 
     item_text_node.value = ''; 
     var item_list = document.getElementById('item-list-2'); 
     item_list.appendChild(item_clone); 
    } else { 
     alert('No text?? Add some text!'); 
    } } 

function onEnterInInput() { 
    var e = e || window.event; 
    if (e.keyCode == 13) { 
     add_item() 
    } } 

function sample_data() { 
    for(var i=0;i<10;i++){ 
     var item_text_node = document.getElementsByName('add-item-text')[0] 
     item_text_node.value = i; 
     var item_text_node_2 = document.getElementsByName('add-item-text-2')[0] 
     item_text_node_2.value = i; 
     add_item(); 
     add_item_2(); 
    } } 

window.onload = function() { 
    sample_data(); } 

HTML代碼:

<!DOCTYPE html> 
<html> 
<head> 
    <title>List task</title> 
    <script type="text/javascript" src="list-task.js"></script> 
    <link rel="stylesheet" type="text/css" href="list-task.css"> 
    <script> 
     document.write('<script src="http://' + (location.host || 'localhost').split(':')[0] + 
     ':35729/livereload.js?snipver=1"></' + 'script>') 
    </script> 
</head> 
<body> 
    <div id="container"> 
     <div id="list-1"> 
      <div id="add-item-div"> 
       <input type="text" name="add-item-text" onkeypress="onEnterInInput(event);"> 
       <button id="add-item" onclick="add_item(event)">Add Item</button> 
      </div> 
      <div id="item-list"> 
      </div> 
     </div> 
     <div id="list-2"> 
      <div id="add-item-div-2"> 
       <input type="text" name="add-item-text-2" onkeypress="onEnterInInput(event);"> 
       <button id="add-item-2" onclick="add_item_2(event)">Add Item</button> 
      </div> 
      <div id="item-list-2"> 
      </div> 
     </div> 
     <div id="item-template-container" class="item-template-container" draggable="true" ondragstart="listItemDragStartHandler(event);" ondragover="dragoverHandler(event);" ondragend="dragEndHandler(event);" ondragleave="dragLeaveHandler(event);" ondrop="onDropHandler(event);"> 
      <div class="item-list-element"> 
       <div class="item-text"></div> 
       <div class="delete-item-div"> 
        <button class="delete-item" onclick="delete_item(event);">Delete</button> 
       </div> 
      </div> 
     </div> 
     <div id="empty-node">&nbsp;</div> 
    </div> 
</body> 
</html> 

視頻描述錯誤:https://www.youtube.com/watch?v=Uz_ukKdg1O0&feature=youtu.be

注意:我觀察到Mac上的行爲,不知道Linux和視窗。

+0

動畫不工作的jsfiddle。 –

+0

這是在鉻與PC的工作權利。 –

+0

好吧,但正如你可以在視頻中它發生在Mac的所有瀏覽器。我應該製作另一個視頻嗎? – igaurav

回答

0

在您的dragend事件處理程序中,您需要檢測鼠標是否在要放入其中的列表中的灰色框上。請注意,您需要編寫查詢元素grayBoxInOtherList的邏輯,但這是您將要執行的操作需要做的:

if ($(grayBoxInOtherList).parent().find(":hover")) { 
    listContainer.insertBefore(source, grayEmptyNode); 
} 

只有做到這一點,如果你將鼠標懸停在grayBoxInOtherList:listContainer.insertBefore(source, grayEmptyNode);

+0

UX不需要用戶將鼠標懸停在灰色框上,用戶可以選擇將其從任何位置在瀏覽器中。所以這個解決方案不是我所需要的。 – igaurav

+0

從您的視頻中,我認爲如果您當前沒有將鼠標懸停在新列表上的灰色框中,我認爲您想返回原始位置。你能否澄清所需的行爲? –