基于HTML5拖放事件的叠加层闪烁问题

8
我正在尝试实现一个拖放上传器,当文件被拖入窗口时,使用一个覆盖层(在dropzone内部的100%宽度/高度绝对元素,在静态状态下看起来很棒)标记dropzone,并在文件离开窗口或在dropzone外部被放下时删除该标记。
问题是,当文件被拖入窗口时,dragover和dragleave事件会不断触发,因此覆盖层会不停地闪烁。
window.addEventListener('dragover', handleDrag, false);
window.addEventListener('dragleave', handleStop, false);
window.addEventListener('drop', handleStop, false);
dropzone.addEventListener('drop', handleUpload, false);

function handleDrag(event) {
  // Stop normal browser response.
  event.stopPropagation();
  event.preventDefault();

  if (!window.mysettings.dragging) {
    window.mysettings.dragging = true;
    $('#dropzone').prepend('<div class="overlay">HELLO</div>');
  }
}

function handleStop(event) {
  // Stop normal browser response.
  event.stopPropagation();
  event.preventDefault();

  if (window.mysettings.dragging) {
    window.mysettings.dragging = false;
    $('#dropzone .overlay').remove();
  }
}

function handleUpload(event) {
  // Stop normal browser response.
  event.stopPropagation();
  event.preventDefault();

  if (window.mysettings.dragging) {
    window.mysettings.dragging = false;
    $('#dropzone .overlay').remove();
  }

  // DO MY FILE UPLOAD STUFF HERE
}

你想要使用 dragenter 而不是 dragover 吗? - Christian
也许吧。我改用dragenter,虽然闪烁现象减少了,但问题仍然存在。 - obrienmd
基本问题在于当元素变得可见时,dragLeave事件被触发。我也遇到了这个问题,并尝试使用添加样式而不是添加和删除覆盖层元素的方法来解决它,但没有成功。 - ohcibi
你能否在 http://jsfiddle.net/ 上创建一个与你的代码相关的示例? - alebruck
2个回答

2
http://jsbin.com/zabeqigefi/1/edit?css,js,output

嘿,
实际上正在发生的事情是:

  1. You're prepending/removing item nearly 60 times per second or so.
  2. You can't show full-width overlay over active element! If you're doing so, when overlay is active dragleave will be fired when you're moving mouse around.
  3. I got this from dropbox website - they have four segments to show dropzone activation - like these (it's borders top, bottom, left, right ones):

    <div style="opacity: 0.6; /* display: none; */" class="external-drop-indicator top"></div>
    <div style="opacity: 0.6; display: none;" class="external-drop-indicator right"></div>
    <div style="opacity: 0.6; display: none;" class="external-drop-indicator bottom"></div>
    <div style="opacity: 0.6; display: none;" class="external-drop-indicator left"></div>
    

祝你好运!

P.S. - 你可以在body上添加一个类而不是创建新的节点,并通过css改变dropzone的视图。


1
在我的项目中,我发现以下属性会闪烁:
  • visibility:hiddenvisibility:visible
  • display:nonedisplay:block
但以下属性不会闪烁:
  • opacity:0opacity:1
另外,请确保在HTML中,遮罩元素出现在活动区域元素之前。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接