如何使用窗口覆盖和多个放置区域处理文件拖放?

时间:2017-07-07 15:05:31

标签: javascript drag-and-drop dropzone.js

我希望能够检测到用户何时将文件拖入窗口并在整个应用上弹出覆盖图,其中显示了用户可以将文件上传到的各种文件夹。

到目前为止,据我所知,我可以在窗口中听到" dragenter"并显示我的叠加层,然后聆听叠加层" dragleave"隐藏它,但问题似乎是拖动拖放区域会导致叠加的dragleave事件触发,这会使叠加隐藏(这使窗口dragenter事件显示叠加,等等)。 / p>

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

修改:我在StackOverflow的其他地方找到了一个解决方案({3}}

解决方法是检查dragleave上的事件,如果pageX和pageY都是0,那么这意味着dragleave是因为用户离开了窗口,而不是拖过其中一个下拉区域。

2 个答案:

答案 0 :(得分: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);
}

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

答案 1 :(得分:0)

在这个特定场景中(在全屏叠加中使用Dropzone实例,只有在拖动文件时才能看到,而你只希望用户将文件拖放到dropzones而不是整个叠加层),这就是我所做的解决问题。

  • 在窗口上聆听" dragenter"
    • 如果事件dataTransfer对象有一个类型数组,其中包含1个项目且类型为[0] =="文件"然后显示叠加层(这样我们就不会显示叠加层,如果有文字被拖动的话)
  • 聆听" dragleave"
    • 如果dragleave事件pageX和pageY都是0,则用户拖出文档,我们应该隐藏叠加层,否则它们会拖动其中一个下拉区域
  • 聆听" dragover"
    • 如果屏幕上有任何元素" dz-drag-hover"然后将事件dataTransfer.dropEffect设置为" copy"因为我们正在徘徊在dropzone上
    • else将事件dataTransfer.dropEffect设置为" none"和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);