2

我对 HTML5 中的拖放有一个奇怪的问题。

有 3 个目标区域是包含文本的 div,还有 1 个源区域是包含图像的 div。

我使用 dragenter 和 dragleave 事件来更改活动目标区域的边界,以投影拖动对象将要降落的位置。

问题是,一旦您将它拖到文本上,它就会出于某种原因触发 dragleave 事件,从而移除边框。

这是一个说明问题的 jsfiddle 示例

这是一些内联代码:

HTML

<h1>Targets</h1>
<div class="targets">
    <div class="target">I am a target<br/>Touch text while dragging to see the problem</div>
    <div class="target">I am a target<br/>Touch text while dragging to see the problem</div>
    <div class="target">I am a target<br/>Touch text while dragging to see the problem</div>
</div>
<h1>Source</h1>
<div class="source" draggable="true">
    <img class="source_image" src="http://lorempixel.com/output/technics-q-c-184-69-8.jpg" alt="image" width="184" height="69"/>
</div>

JS

$("div.source").on('dragstart', function(e) {
    $(this).fadeTo('slow', 0.4);
});

$("div.source").on('dragend', function(e) {
    $(this).fadeTo('slow', 1);
});

$("div.target").on('dragover', function(e) {
    if (e.preventDefault) {
        e.preventDefault();
    }

    e.dataTransfer.dropEffect = 'move';

    return false;
});

$("div.target").on('dragenter', function(e) {
    $(this).addClass('over');
});

$("div.target").on('dragleave', function(e) {
    $(this).removeClass('over');
});

CSS

h1 {
    font-size: 2em;
    text-align: center;
}

.target {
    margin: 1em;
    display:inline-block;
    width: 184px;
    height: 69px;
    border: 5px #995555 solid;
    border-radius: 5px;
    background-color: #AAAAAA;
    vertical-align: bottom;
    text-align: center;
    font-size: 1.1em;
    font-weight: bold;
    line-height: 0.9em;
}

.target.over {
    border: 5px #0A0 dashed;
}

.source {
    margin: 1em;
    display:inline-block;
    width: 184px;
    height: 69px;
    border: 5px #555599 solid;
    border-radius: 5px;
    background-color: #CCCCCC;
    vertical-align: bottom;
    text-align: center;
    font-size: 1.4em;
    font-weight: bold;      
}

有谁知道即使在触摸文本时也能保持边框变化的任何解决方案?

另一个问题是是否可以保持源 div 周围的边框被拖动?

最后一点,我意识到这两件事都可以通过使用 jQuery UI 拖放来完成,但我特别想知道是否可以使用原生 HTML5 拖放来做到这一点。

4

1 回答 1

2

问题是文本在 DOM 中构成了一个额外的节点,dragleave并且dragenter考虑了子元素和父元素。当光标进入文本节点时,它会离开div. 这类似于mouseoutvsmouseleave问题。解决此问题的一种简单方法是记录事件的数量,并且仅在考虑所有事件后才删除样式:

var count=0;
$("div.target").on('dragenter', function(e) {
    $(this).addClass('over');
    count++;
}).on('dragleave', function(e) {
    if (--count<=0) {
        $(this).removeClass('over');
    }
});

这不一定完全可靠(请记住count在事件中设置为零drop),但它会比您当前的设置更好。另一种选择是根本不将任何内容放入div元素中,而是使用 CSS 添加:

.target:after {
    content: 'I am a target \A Touch text while dragging to see the problem';
    white-space: pre-wrap;
}

这有一些可访问性的缺点,因为生成的内容对辅助技术是不可见的,并且只会让您添加文本,但在许多方面是一种更清洁的解决方案

于 2012-12-28T18:01:23.937 回答