Как определить, что файл перетаскивается, а не перетаскиваемый элемент на моей странице?
Я использую события html5, чтобы включить и перетаскивание файлов и элементов. Я привязал событие dragover к телу и использую делегаты событий, чтобы показать, куда можно отбросить draggable. Мой вопрос в том, как я могу определить, перетаскивается ли файл против элемента с draggable = true. Я знаю, что могу обнаружить, что элемент перетаскивается через e.target. Но, как я могу определить, является ли это файлом.
Доступен jquery.
Кроме того, не говорит о jquery-ui, перетаскиваемом здесь.
Я начинаю думать, что единственный способ обнаружить файл - это исключение и обнаружение элементов. Если мы не перетаскиваем элемент, предположим, что это файл. Это потребует дополнительной работы, хотя по умолчанию перетаскиваются изображения и ссылки, поэтому мне придется добавлять к ним события или препятствовать их перетаскиванию.
Ответы
Ответ 1
Вы можете обнаружить, что перетаскивается, проверяя 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
Ответ 2
Дальнейшее улучшение ответа на букет:
Так как chrome вызывает dragleave документа на каждом dragenter враге каждого элемента, это может вызвать мерцание 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);
});
btw, спасибо за идею! Мое другое решение было абсолютной болью:)
Ответ 3
Я просто использую это для обнаружения файлов в событии dragover
:
Array.prototype.indexOf.call(files, "Files")!=-1 // true if files
Ответ 4
Я не совсем понимаю вашу текущую ситуацию, но если ваш элемент - объект с возможностью перетаскивания, я думаю, вы можете обернуть его внутри другого объекта с другим идентификатором для файлов и обычных элементов? Поэтому, когда вы вызываете событие, вы можете проверить его идентификатор перед обработкой. Надеюсь, это поможет! =)
Ответ 5
Используйте приведенную ниже функцию, чтобы проверить, является ли источник перетаскивания внешним файлом.
Протестировано в 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);
});