1

I am doing a research work on HTML5 Drag and Drop concept by referring this link. Currently, I am facing a problem on dragenter event which is firing for the second time (for child element) before dragleave. Therefore, the dashed border style which I have given when dragenter is not removing after dragleave in some cases. When I searched in Google, I referred some links and this link but still couldn't fix the issue. I added CSS property pointer-events: none but that is not compatible in IE9 and IE10.

Please note I need compatibility on IE9 and above, Mozilla too.

PFB the code snippet.

var dragSrcEl = null;
var dragEnteredSrcEl = null;
var collection = $();

function handleDragStart(ev) {
    dragSrcEl = ev.target;

    ev.target.style.opacity = 0.4;
    ev.target.classList.add('moving');

    ev.dataTransfer.setData('text/html', ev.target.innerHTML);
}

function handleDragOver(ev) {
    ev.preventDefault();
}

function handleDragEnter(ev, el) {
    ev.stopPropagation();
    console.log('drag enter!');
    var dragEnteringElement = ev.target;
    collection = collection.add(dragEnteringElement);
    // dragEnteredSrcEl = dragEnteringElement;
    el.classList.add('over');
}

function handleDrop(ev, el) {
    // console.log(ev.target);
    var droppingElement = el;
    // Don't do anything if dropping the same column we're dragging.
    if (dragSrcEl != ev.target) {
        // Set the source column's HTML to the HTML of the column we dropped on.
        dragSrcEl.style.opacity = 1;
        dragSrcEl.innerHTML = droppingElement.innerHTML;
        droppingElement.classList.remove('over');
        droppingElement.innerHTML = ev.dataTransfer.getData('text/html');
    }
}

function handleDragLeave(ev, el) {
    // console.log(ev.target);
    setTimeout(function() {
        var dragLeavingElement = ev.target;    
        console.log(collection.length);    
        collection = collection.not(dragLeavingElement);
        if (collection.length === 0) {
            console.log('drag leave!');
            el.classList.remove('over');
        }
    }, 1);
}

function handleDragEnd(ev) {
    ev.target.style.opacity = 1;
    ev.target.classList.remove('moving');
    ev.target.classList.remove('over');
}

function handleContentClick(content) {
    alert(content);
}
.clearfix {
    clear: both;
}

[draggable] {
    cursor: move;
}

.col-md-4 {
    width: 150px;
    height: 150px;
    border: 2px solid orange;
    float: left;
    margin-top: 5px;
    margin-right: 5px;
    text-align: center;
}

.col-md-4.over {
    border-style: dashed;
}

/* .col-md-4 h2 {
    pointer-events: none;
} */
<div class="container">
        <div class="col-md-4" draggable="true" ondragstart="handleDragStart(event)" ondrop="handleDrop(event, this)" ondragenter="handleDragEnter(event, this)" ondragover="handleDragOver(event)" ondragleave="handleDragLeave(event, this)" ondragend="handleDragEnd(event)">
            <h2 onclick="handleContentClick('Hello!')">Hello!</h2>
        </div>
        <div class="col-md-4" draggable="true" ondragstart="handleDragStart(event)" ondrop="handleDrop(event, this)" ondragenter="handleDragEnter(event, this)" ondragover="handleDragOver(event)" ondragleave="handleDragLeave(event, this)" ondragend="handleDragEnd(event)">
            <h2 onclick="handleContentClick('Welcome!')">Welcome!</h2>
        </div>
        <div class="col-md-4" draggable="true" ondragstart="handleDragStart(event)" ondrop="handleDrop(event, this)" ondragenter="handleDragEnter(event, this)" ondragover="handleDragOver(event)" ondragleave="handleDragLeave(event, this)" ondragend="handleDragEnd(event)">
            <h2 onclick="handleContentClick('World!')">World!</h2>
        </div>
        <div class="clearfix"></div>
        <div class="col-md-4" draggable="true" ondragstart="handleDragStart(event)" ondrop="handleDrop(event, this)" ondragenter="handleDragEnter(event, this)" ondragover="handleDragOver(event)" ondragleave="handleDragLeave(event, this)" ondragend="handleDragEnd(event)">
            <h2 onclick="handleContentClick('Big Hello!')">Big Hello!</h2>
        </div>
        <div class="col-md-4" draggable="true" ondragstart="handleDragStart(event)" ondrop="handleDrop(event, this)" ondragenter="handleDragEnter(event, this)" ondragover="handleDragOver(event)" ondragleave="handleDragLeave(event, this)" ondragend="handleDragEnd(event)">
            <h2 onclick="handleContentClick('Big Welcome!')">Big Welcome!</h2>
        </div>
        <div class="col-md-4" draggable="true" ondragstart="handleDragStart(event)" ondrop="handleDrop(event, this)" ondragenter="handleDragEnter(event, this)" ondragover="handleDragOver(event)" ondragleave="handleDragLeave(event, this)" ondragend="handleDragEnd(event)">
            <h2 onclick="handleContentClick('Big World!')">Big World!</h2>
        </div>
    </div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Thanks in advance.

Abraham Gnanasingh
  • 837
  • 2
  • 10
  • 31

2 Answers2

2

You should use event.stopPropagation(); who prevents the event from beeing trigger with the children elements.

There is the doc : https://api.jquery.com/event.stoppropagation/

0

Its a Firefox-Bug. In Firefox the "Dragenter-Event" gets fired twice. No matter if there is any child-element or not. You could try to work with event.target and event.currentTarget in combination with pointer-events: none.