javascript - without - html5 draggable iframe



Comment arrêter le comportement par défaut de Dragend par glisser-déposer? (1)

J'ai du mal à résumer ce bug en mots. J'ai donc fait la vidéo pour le bug. Fondamentalement, quand dragEnd est appelé, l'élément s'anime comme s'il allait à l'endroit d'origine. Comment arrêter le comportement par défaut? J'ai fait du violon et du codepen pour ça aussi.

J'ai deux liste pour mon exemple, en appelant dragEnd après avoir relâché le bouton de la souris. L'élément d'une liste anime aller à la liste de son lieu d'origine au lieu de l'endroit où il va être.

Code 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(); }

Code 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>

Vidéo décrivant le bug: https://www.youtube.com/watch?v=Uz_ukKdg1O0&feature=youtu.be

Note : J'ai observé le comportement sur Mac, pas sûr de Linux et de Windows.


Dans votre gestionnaire d'événements dragend, vous devez détecter si la souris se trouve au-dessus de la zone grise de la liste dans laquelle vous souhaitez la déposer. Notez que vous devrez écrire la logique pour interroger l'élément grayBoxInOtherList mais grayBoxInOtherList ce que vous devrez faire:

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

N'effectuez cette opération que si vous passez la souris sur grayBoxInOtherList: listContainer.insertBefore(source, grayEmptyNode);





drag-and-drop