如何检测正在拖动的文件,而不是我的网页上的可拖动元素?

我正在使用html5事件来启用文件和元素拖放。 我将dragover事件附加到body上,并使用事件代理来显示拖放的位置。 我的问题是我怎么能告诉如果一个文件被拖动与draggable = true的元素。 我知道我可以检测到通过e.target被拖动的元素。 但是,我怎么知道它是否是一个文件。

jquery可用。

另外, 不要在这里讨论jQuery的可拖动。

我开始思考也许检测文件的唯一方法是排除和检测元素。 如果我们不拖动元素,则假定它是一个文件。 这将需要额外的工作,虽然图像和链接默认是可拖动的,所以我将不得不添加事件给他们,或阻止他们拖动。

您可以通过检查dataTransfer.types来检测正在拖动的内容。 这种行为在浏览器中还没有一致,所以你必须检查'Files' (Chrome)和'application/x-moz-file' (Firefox)的存在。

 // Show the dropzone when dragging files (not folders or page // elements). The dropzone is hidden after a timer to prevent // flickering to occur as `dragleave` is fired constantly. var dragTimer; $(document).on('dragover', function(e) { var dt = e.originalEvent.dataTransfer; if (dt.types && (dt.types.indexOf ? dt.types.indexOf('Files') != -1 : dt.types.contains('Files'))) { $("#dropzone").show(); window.clearTimeout(dragTimer); } }); $(document).on('dragleave', function(e) { dragTimer = window.setTimeout(function() { $("#dropzone").hide(); }, 25); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="dropzone" style="border: 2px dashed black; background: limegreen; padding: 25px; margin: 25px 0; display: none; position"> 🎯 Drop files here! </div> 📄 hover files here 

bouke的答案进一步改进:

由于chrome在每个元素上都会调用文档的dragleave,所以会造成dropzone的闪烁,特别是嵌套元素多的情况。

 $(document).on('dragleave', function(e) { dragTimer = window.setTimeout(function() { $("#dropzone").hide(); }, 25); }); 

我所做的解决这个问题的方法是稍微增加超时时间,并在设置每个超时之前添加clearTimeout,因为之前在某些情况下会有多个超时事件在dragover事件中不被清除,因为dragTimer只存储最新一。 结果版本:

 $(document).on('dragleave', function(e) { window.clearTimeout(dragTimer); dragTimer = window.setTimeout(function() { $("#dropzone").hide(); }, 85); }); 

顺便说一句,谢谢你的想法! 我的另一个解决scheme是绝对痛苦:)

我只是用它来检测dragover事件中的文件:

 Array.prototype.indexOf.call(files, "Files")!=-1 // true if files 

我不完全了解你目前的情况,但如果你的元素是一个可拖拽的对象,我想你可以把它包装在另一个不同的文件和普通元素的id对象? 所以当你调用一个事件时,你可以在处理之前检查它的id。 希望这可以帮助! =)

使用下面的function来检查拖动源是否是外部文件。

testing在Windows 7上:

  • Firefox版本39
  • Chrome版本44
  • Safari版本5.1.7
 function isDragSourceExternalFile(dataTransfer){ // Source detection for Safari v5.1.7 on Windows. if (typeof Clipboard != 'undefined') { if (dataTransfer.constructor == Clipboard) { if (dataTransfer.files.length > 0) return true; else return false; } } // Source detection for Firefox on Windows. if (typeof DOMStringList != 'undefined'){ var DragDataType = dataTransfer.types; if (DragDataType.constructor == DOMStringList){ if (DragDataType.contains('Files')) return true; else return false; } } // Source detection for Chrome on Windows. if (typeof Array != 'undefined'){ var DragDataType = dataTransfer.types; if (DragDataType.constructor == Array){ if (DragDataType.indexOf('Files') != -1) return true; else return false; } } } 

使用JQuery的示例

 $(document).on('dragover', function(e){ var IsFile = isDragSourceExternalFile(e.originalEvent.dataTransfer); console.log(IsFile); });