【问题标题】:dragenter calling twice before dragleave in html5 drag and dropdragenter 在 html5 拖放之前调用两次
【发布时间】:2018-03-16 12:04:28
【问题描述】:

我正在通过引用link 对 HTML5 拖放概念进行研究。目前,我在dragenter 事件上遇到问题,该事件在dragleave 之前第二次触发(针对子元素)。因此,在某些情况下,dragenter 时我给出的虚线边框样式在 dragleave 之后没有删除。当我在谷歌中搜索时,我提到了一些链接和这个link,但仍然无法解决这个问题。我添加了 CSS 属性 pointer-events: none 但在 IE9 和 IE10 中不兼容。

请注意,我需要兼容 IE9 及更高版本,Mozilla 也是如此。

PFB 代码 sn-p。

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>

提前致谢。

【问题讨论】:

    标签: javascript jquery html css


    【解决方案1】:

    您应该使用event.stopPropagation(); 来防止事件与子元素一起触发。

    有文档:https://api.jquery.com/event.stoppropagation/

    【讨论】:

    • 你能告诉我应该在哪里使用这个event.stopPropagation()吗?
    • 函数开头有问题:handleDragEnter。尝试把 event.stopPropagation();
    • 我尝试在 handleDragEnter 中添加event.stopPropagation(),但问题仍然存在。更改代码 sn-p 也与 event.stopPropagation()
    【解决方案2】:

    它是一个 Firefox 错误。在 Firefox 中,“Dragenter-Event”被触发两次。不管是否有任何子元素。 您可以尝试将 event.target 和 event.currentTarget 与 pointer-events: none 结合使用。

    【讨论】:

      猜你喜欢
      • 2020-04-03
      • 2015-12-17
      • 1970-01-01
      • 2011-04-11
      • 1970-01-01
      • 1970-01-01
      • 2011-07-28
      • 2023-03-16
      • 1970-01-01
      相关资源
      最近更新 更多