我编写了一个脚本和 html 页面来测试一些拖放功能,其中将文件系统中的文件拖放到我定义的浏览器放置目标中。
在这种环境下,我总是能够访问event.dataTransfer.files
然而,我已经将它集成到一个 JSF servlet 中,突然间行为变得不那么一致了。
我现在看到,在 dragover 事件中,文件列在下面event.dataTransfer.items
但event.dataTransfer.files
为空。DataTransferItem
object 似乎引用了 mimeType 但不是数据本身,也不是像 aFile
那样的文件名。然而在 drop 事件中,event.dataTransfer.files
包含文件。
此外,所有 getAs 方法DataTransferItem
都返回 null。我可以解决一些问题,因为我只是真的想在 dragover 事件中找出文件类型,但我至少想弄清楚这些特殊行为。
我不确定这种变化是由什么引起的。实际的脚本没有改变,相关的标记都是纯 HTML 而不是 JSF 组件。为什么行为发生了变化?
编辑:可能值得注意的是,我使用的 JSF 实现是 Primefaces,它包含一个 jQuery 版本,它可能比我本周从 jQuery 网站上提取的最新版本更旧。
JS:
var CSVParser = (function($) {
"use strict";
var module = {
/**
* Inspects the file's name and mime-type to determine if it is a CSV file. Does not inspect
* contents.
* supports any mime type that contains csv, is comma-separated-values, or is application/vnd.ms-excel
* @param file - javascript file
*/
isCSV: function(file) {
if(file) {
var mimeType = file.type;
var name = file.name || ".csv"; //Deal with possibly getting a DataTransferItem instead of File object. Just assume .csv
var matchStandardMime = mimeType.match(/.*\/csv.*/) !== null || mimeType.match(/comma-separated-values/) !== null;
var matchExcelMime = mimeType.match(/application\/vnd.ms-excel/) !== null;
matchExcelMime = matchExcelMime && name.match(/.*\.csv/) !== null;
return matchStandardMime || matchExcelMime;
}
}
};
return module;
}(jQuery));
(function($){
/* Deal with drop-files */
function getDropbox() {
return $('.csvDropTarget');
}
function getEventFiles(e) {
var files = e.originalEvent.dataTransfer.files || []; //jQuery seems to wrap the original event
var items = e.originalEvent.dataTransfer.items || []; //jQuery seems to wrap the original event
e.originalEvent.dataTransfer.dropEffect = 'copy';
if(files.length > 0) {
return files;
} else if (items.length > 0) {
return items;
}
return files;
}
function onDragEnter(e) {
e.stopPropagation();
e.preventDefault();
}
function onDragOver(e) {
var files = getEventFiles(e);
var validDrop = false;
e.stopPropagation();
e.preventDefault();
for(var i = 0; i < files.length; i++) {
if(files[i] && CSVParser.isCSV(files[i])) {
validDrop = true;
} else {
validDrop = false;
break;
}
}
}
function onDragLeave(e) {
e.stopPropagation();
e.preventDefault();
}
function onDrop(e) {
var files = getEventFiles(e);
var file = null;
e.stopPropagation();
e.preventDefault();
// Loop through list of files user dropped.
for (var i = 0; i < files.length; i++) {
file = files[i];
console.log("File type: " + file.type);
console.log("Is CSV: " + CSVParser.isCSV(file));
}
}
/* Register events and determine functionality */
$(document).ready(function() {
var dropbox = getDropbox();
dropbox.bind("dragenter", onDragEnter);
dropbox.bind("dragover", onDragOver);
dropbox.bind("dragleave", onDragLeave);
dropbox.bind("drop", onDrop);
});
}(jQuery));
HTML 片段:
<div class="csvDropTarget mainDropTarget">
<span class="dragDropText">${resourceBundle.csv_drag_prompt}</span>
<span class="validDropText hidden">${resourceBundle.csv_valid_drag}</span>
<span class="invalidDropText hidden">${resourceBundle.csv_invalid_drag}</span>
</div>