web-dev-qa-db-ja.com

ページ上のドラッグ可能な要素ではなく、ファイルがドラッグされていることをどのように検出しますか?

ファイルと要素の両方のドラッグアンドドロップを有効にするためにhtml5イベントを使用しています。ドラッグオーバーイベントをボディに添付し、イベントデリゲーションを使用して、ドラッグ可能オブジェクトをドロップできる場所を示しています。私の質問は、ファイルがドラッグされているか、draggable = trueの要素であるかをどのように判断できるかです。 e.targetを介してドラッグされている要素を検出できることはわかっています。しかし、それがファイルかどうかはどうすればわかりますか。

jqueryが利用可能です。

また、notここでドラッグ可能なjquery-uiについて話します。

ファイルを検出する唯一の方法は、代わりに除外して要素を検出することによるものだと私は考え始めています。要素をドラッグしていない場合は、ファイルであると想定します。ただし、画像とリンクはデフォルトでドラッグ可能であるため、追加の作業が必要になるため、イベントを追加するか、ドラッグできないようにする必要があります。

40
aepheus

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
68
Bouke

Boukeの回答のさらなる改善:

chromeは各要素のすべてのdragenterでドキュメントのdragleaveを呼び出すため、特にネストされた要素が多い場合、ドロップゾーンのちらつきを引き起こす可能性があります。

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

この問題を解決するために私がしたことは、タイムアウトを少し増やし、各タイムアウトを設定する前にclearTimeoutを追加することです。 1。結果のバージョン:

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

ところで、アイデアをありがとう!私の他の解決策は絶対的な痛みでした:)

6
elanoism

これを使用して、dragoverイベントのファイルを検出します。

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

以下の関数を使用して、ドラッグソースが外部ファイルかどうかを確認します。

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