上传文件时检测到取消的拖放操作

Posted

技术标签:

【中文标题】上传文件时检测到取消的拖放操作【英文标题】:Detecting a cancelled drag and drop action when uploading files 【发布时间】:2012-07-05 16:15:21 【问题描述】:

这是我想要的行为:

    用户开始从文件资源管理器中拖动文件 当文件悬停在浏览器窗口上时,会出现 3 个拖放区 当用户取消拖放或拖放文件时,拖放区消失。

我遇到的问题是#3。 在document 上使用dragenter 时,拖放区看起来很好,但我无法让它们再次消失。

我尝试绑定dragend,它永远不会触发,dragleave 每次拖动离开后代时都会触发,因此拖动区域会闪烁。

哪个事件是正确的听?

【问题讨论】:

【参考方案1】:

我尚未对其进行全面测试,但您似乎可以利用 dragenterdragleave 的烦人行为,它们会在每个元素上触发。

var counter = 0;
$(document).on('dragenter', function ()  
  if (counter++ === 0) 
    console.log('entered the page');
  
);

$(document).on('dragleave', function () 
  if (--counter === 0) 
    console.log('left the page');
  
);

如果通过按 Escape 取消拖动,似乎也可以工作。

http://jsbin.com/atodem/2/

【讨论】:

别忘了添加 Dragover 以防止默认拖放,而且完全按照我的意愿工作! 小心,因为这很容易损坏。检查这个fiddle,它只显示其中一个问题。检查my answer 以获取替代方案。 在 Chrome 和 Firefox 上就像一个魅力,但在 IE 11 上计数器有时会出错。【参考方案2】:

document 上,您想同时收听dragleavedragover,以分别隐藏和显示区域。

【讨论】:

问题是我想淡入 dropzones 并且在移动文件时会导致错误(dropzones 闪烁)。我猜这是由于事件的传播。 如果我不使用 display: none 隐藏/显示拖放区,它会起作用,但这样用户仍然可以与它们交互,这很糟糕。 是什么导致了闪烁,dragleave? 是的,dragleave 可悲地冒泡到文档中。 我通过解决问题解决了这个问题,但感谢您的意见!【参考方案3】:

好吧,dragstartdragend 事件似乎只在将某些东西浏览器拖到浏览器时触发,这在您的情况下几乎没有用处。我似乎无法停止闪烁,但如果您为 dragenterdragleave 事件添加超时,您可以将闪烁最小化:

window.onload=function()
    var drag = new (function()
        var timeout;
        this.detected = function()
            return !(timeout === undefined)
        
        this.start = function()
            clearTimeout(timeout);
        
        function endDrag()
            for (var i=0;i<3;i++) //no longer dragging, remove drop zones
                document.getElementsByClassName("dropZone")[i].style.display="none";
        
        this.end = function()
            timeout = setTimeout((function()timeout=undefined;endDrag();),1500)
        
    )()
    document.body.ondragenter = function()
        drag.start();
        for (var i=0;i<3;i++) //drag started, show drop zones
            document.getElementsByClassName("dropZone")[i].style.display="block";
    
    document.body.ondragleave = function(event)
        event = event||window.event
        if ((event.source||event.target)==document.body)
            drag.end();
    

希望对您有所帮助,如果不完美,请见谅。 :-(

【讨论】:

【参考方案4】:

您可以通过检查是否在 dragend 之前调用 drop 来验证它。

     var dragConfirmed;

     document.addEventListener("drop", function( event ) 
          // prevent default action (open as link for some elements)
          event.preventDefault();

          dragConfirmed = true;
      , false);



      document.addEventListener("dragend", function( event ) 

        if (dragConfirmed != true)
        
             // Escape has been pressed
        

      , false);

【讨论】:

【参考方案5】:

dragleave 对我不起作用。我使用了超时:

function stopDrag()
   console.log('bye drag!');


var timeoutHandle;
document.addEventListener('dragover', function()
    console.log('you are dragging');
    window.clearTimeout(timeoutHandle);
    timeoutHandle = window.setTimeout(stopDrag, 200);
, false);

【讨论】:

以上是关于上传文件时检测到取消的拖放操作的主要内容,如果未能解决你的问题,请参考以下文章

在 Asp.net 中使用 HTML5 的拖放上传文件

用于 Internet Explorer 的拖放文件上传库

.net的拖放文件上传插件?

selenium怎么实现文件拖拽上传功能

JQuery - 拖放文件 - 如何获取文件信息?

有没有好的 jQuery 拖放文件上传插件?