it-roy-ru.com

Как определить, что файл перетаскивается, а не перетаскиваемый элемент на моей странице?

Я использую события html5, чтобы включить как перетаскивание файлов, так и элементов. Я прикрепил событие dragover к телу и использую делегирование событий, чтобы показать, где можно удалить перетаскиваемый объект. Мой вопрос: как я могу определить, перетаскивается ли файл по сравнению с элементом с draggable = true. Я знаю, что могу обнаружить перетаскиваемый элемент через e.target. Но как я могу сказать, если это файл.

jQuery доступен.

Кроме того, нет говоря о jquery-UI перетаскиваемых здесь.

Я начинаю думать, что, возможно, единственный способ обнаружить файл - это исключение и обнаружение элементов. Если мы не перетаскиваем элемент, предположим, что это файл. Это потребует дополнительной работы, так как изображения и ссылки по умолчанию перетаскиваются, поэтому мне придется добавлять к ним события или предотвращать их перетаскивание.

37
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

61
bouke

Дальнейшее улучшение ответа букэ:

Так как Chrome вызывает перетаскивание документа на каждом перетаскивающем элементе для каждого элемента, это может вызвать мерцание зоны сброса, особенно если имеется много вложенных элементов.

$(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);
});

кстати, спасибо за идею! Мое другое решение было абсолютной болью :)

6
elanoism

Я просто использую это для обнаружения файлов в событии dragover:

Array.prototype.indexOf.call(files, "Files")!=-1 // true if files
4
Tomáš Zato

Используйте функцию ниже, чтобы проверить, является ли источник перетаскивания внешним файлом.

Протестировано на 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
Shannon