我编写了一个脚本和 html 页面来测试一些拖放功能,其中将文件系统中的文件拖放到我定义的浏览器放置目标中。
在这种环境下,我总是能够访问event.dataTransfer.files
然而,我已经将它集成到一个 JSF servlet 中,突然间行为变得不那么一致了。
我现在看到,在 dragover 事件中,文件列在下面event.dataTransfer.items但event.dataTransfer.files为空。DataTransferItemobject 似乎引用了 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>