2017-07-07 99 views
1

我希望能够检测用户何时将文件拖入窗口并弹出覆盖整个应用程序的覆盖图,以显示用户可以上传文件的各种文件夹。如何处理文件拖放与窗口覆盖和多个拖放区域?

到目前为止,我知道我可以听到“dragenter”窗口并显示我的覆盖图,并听取覆盖“dragleave”以隐藏它,但问题似乎是拖过拖放区导致叠加层的dragleave事件触发,这会使叠加层隐藏(这会使窗口dragenter事件显示叠加层,等等)。

我为我的文件夹dropzones使用Dropzone.js。我环顾四周,看到类似的问题,但没有解决这个问题。

编辑:我发现(各种)中的溶液在别处在计算器上:jQuery Drag-and-Drop Flickering on Hover (Webkit only)

的解决方案是检查dragleave事件,并且如果pageX属性和pageY都为0,则这意味着dragleave是因为用户离开了窗户,而不是拖着其中一个下拉区。

+0

对于其目的是要显示的叠加?要停止文件上传? –

+0

该页面默认显示已上传的文件。当用户将文件拖放到屏幕上时,叠加层将显示可以上传的可用文件夹(有点像imgur.com处理文件上载叠加层,除了多个下拉框和全局下拉区)。 因此,叠加的目的是向用户显示文件夹下拉框。 –

+0

你只是想显示覆盖或期待用户输入,如从覆盖选择文件夹? –

回答

0

在这种特定的情况下(在全屏覆盖图中使用Dropzone实例,只有在拖动文件时才可见,并且您只希望用户将文件放到拖放区而不是整个覆盖图),以下是我所做的解决问题。

  • 试听窗口“的dragenter”
    • 上如果事件dataTransfer对象具有类型阵列1项本和类型[0] ==“文件”,然后显示所述覆盖层(这样,我们不显示覆盖,如果是这样的文字被拖动)
  • 听上覆盖的“dragleave”
    • 如果dragLeave事件pageX属性和pageY都为0,则该用户d衣衫褴褛出文档的,我们应该隐藏覆盖,否则会被拖着在dropzones
  • 听上覆盖了“的dragover”之一
    • ,如果有一个在屏幕上的任何元素类“dz-drag-hover”,然后将事件dataTransfer.dropEffect设置为“复制”,因为我们将鼠标悬停在dropzone上。其他事件dataTransfer设置其他事件。DROPEFFECT为 “无” 和preventDefault()方法

下面是上述一些未经检验的javascript:

function handleDragEnter(e) { 
    // make sure we're dragging a file 
    var dt = (e && e.dataTransfer); 
    var isFile = (dt && dt.types && dt.types.length == 1 && dt.types[0] == "Files"); 
    if (isFile) { 
     // and, if so, show the overlay 
     showOverlay(); 
    } 
} 

function handleDragLeave(e) { 
    // was our dragleave off the page? 
    if (e && e.pageX == 0 && e.pageY == 0) { 
     // then hide the overlay 
     hideOverlay(); 
    } 
} 

function handleDragOver(e) { 
    // look for any dropzones being hovered 
    var isHovering = document.getElementsByClassName("dz-drag-hover").length > 0; 
    if (isHovering) { 
     // found some? then we're over a dropzone and want to allow dropping 
     e.dataTransfer.dropEffect = 'copy'; 
    } else { 
     // we're just on the overlay. don't allow dropping. 
     e.dataTransfer.dropEffect = 'none'; 
     e.preventDefault(); 
    } 
} 

function showOverlay() { 
    // only show the overlay if it's not already shown (can prevent flickering) 
    if (getComputedStyle(overlay, null).display == "none") 
     overlay.style.display = "block"; 
    } 
} 

function hideOverlay() { 
    overlay.style.display = "none"; 
} 

// listen to dragenter on the window for obvious reasons 
window.addEventListener("dragenter", handleDragEnter); 
// our fullscreen overlay will cover up the window, so we need to listen to it for dragleave events 
overlay.addEventListener("dragleave", handleDragLeave); 
// same thing for dragover 
overlay.addEventListener("dragover", handleDragOver); 
0

dragleave事件发生得比我们想象的要快,所以我们可以推迟这个过程。

Dropzone.autoDiscover = false; 
$("div#upload").dropzone({ 
    url: "upload.php", 
    addRemoveLinks:true, 
    paramName:"composeUpload", 
    init: function() { 
     myDropZone = this; 
     this.on('dragover', function(e,xhr,formData){ 
      $('.overlay').fadeIn(); 
      stopLoading(); //stops local file opens 
      return false; 
     }); 
     this.on('dragleave', function(e,xhr,formData){ 
      setTimeout(function(){ 
      $('.overlay').fadeIn(); 
      },8000); 
     });   
    } 
}); 

即使你删除的空白div或覆盖浏览器将在本地打开该文件,所以我们必须停止默认

function stopLoading(){ 
    window.addEventListener("dragover",function(e){ 
    e = e || event; 
    e.preventDefault(); 
    },false); 
    window.addEventListener("drop",function(e){ 
    e = e || event; 
    e.preventDefault(); 
    },false); 
} 

我不这是你要找的答案,但文件绝对会给你一个想法。谢谢。