如何检测文件被拖动而不是我页面上的可拖动元素?

时间:2011-07-27 16:38:11

标签: javascript html5 drag-and-drop

我正在使用html5事件来启用文件和元素拖放。我已将dragover事件附加到正文并使用事件委派来显示可拖放的可拖动位置。我的问题是如何判断文件是否被拖动与具有draggable = true的元素。我知道我可以通过e.target检测被拖动的元素。但是,我怎么能判断它是否是一个文件。

jquery可用。

此外,在这里讨论jquery-ui draggable。

我开始认为检测文件的唯一方法是排除并检测元素。如果我们不拖动元素,则假设它是一个文件。这将需要额外的工作,因为默认情况下图像和链接是可拖动的,所以我将不得不向它们添加事件或阻止它们拖动。

4 个答案:

答案 0 :(得分:63)

您可以通过检查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

答案 1 :(得分:6)

进一步改善布克的答案:

由于chrome会在每个元素的每个dragenter上调用文档的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);
});
顺便说一句,谢谢你的想法!我的另一个解决方案是绝对痛苦:)

答案 2 :(得分:4)

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

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

答案 3 :(得分:0)

使用以下功能检查拖动源是否为外部文件。

  

在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);
});