How to select a folder to upload?
In input: File, there is a property that controls which file or folder is displayed when the upload file button is clicked. This property is WebKitDirectory.
Webkitdirectory is an attribute of the file selection tag added in H5, which allows scripts to access local folders. Therefore, when the input:file tag has this attribute, the upload selection will only select the folder, and the file will not be seen. Without this property, in the Select File box, only files can be selected, not folders. The code is as follows:
<input type="file" :accept="accepts" webkitdirectory multiple />Copy the code
As you can see from the code above, we have the webkitDirectory attribute, and now we can select the folder to upload. The actual effect is as follows:
Compatibility with webKitDirectory properties:
As you can see, Google, Firefox, and Edge support this property very well, the rest of the browser does not support this property.
Note 1: When you need to upload folder, you can use this property, then can undertake folder uploaded, but need to be aware of a point is, when you add this attribute, you can only see the folders, when you need to upload files will need to remove this property, can see the file, You need to add and remove this property dynamically to switch between files and folders.
Note 2: folder to upload is not, will the whole folder to upload directly, after the selected folder, the browser will file within the folder read out, regardless of the nested inside layer number is how much of the folder, all the documents will be spread out, then put all the files to upload.
How to drag and drop folders to upload
We achieved two main things:
1. How to drag and drop, and how to read the content after dragging and dropping?
2. How to convert the read content into files one by one?
To achieve 1:
Drag function, now there are many drag methods, I use here is H5 new drag and drop API.
Since my methods are written in vUE, I see the following code:
var dragNow = this.$refs.dragArea;
dragNow.ondragenter = function(e) {
e.preventDefault();
};
dragNow.ondragover = function(e) {
e.preventDefault();
};
dragNow.ondragleave = function(e) {
e.preventDefault();
};
dragNow.ondrop = e= > {
e.preventDefault();
this.dealWithFolders(e.dataTransfer.items);
};Copy the code
DargNow: is the node information obtained by $refs. This node is the area used to place drag-and-drop files or folders
Ondragenter, onDragover, onDragLeave, ondrop. H5 drag-and-drop API:
Ondragenter: Drag and drop just entered the drag and drop area.
Ondragover: Drag-and-drop files above the drag-and-drop area.
Ondragleave: Drags files out of the drag-and-drop area.
Ondrop: Drops the file into the area, then lets go.
Note: e.p reventDefault (); You have to write this inside every action to prevent the default event from happening.
If you drag and drop a file to read e.datatransfer. files you can directly reach the file and upload it; But if it’s a folder, you can’t get the value in this property, because you’re getting information about a folder, not all the files in the folder that you want to get.
At this point, we need to get the property e.datatransfer. items, but it should be noted that this property can not be used directly, we need another method to read the properties in the folder before we can use it.
Implementation 2: How do we read all the files in e.datatransfer. items? This is where these attributes come in
WebkitGetAsEntry: Gets the methods that come with each folder to get the corresponding content.
CreateReader: Reads the folder.
Dirreader. readEntries: Reads and generates files
IsDirectory: indicates whether it is a folder
dealWithFolders(items) {
if (items.length > 1) {
this.loading = false;
return this.$message.info("Upload only one folder at a time.");
}
var item = items[0].webkitGetAsEntry();
if (item) {
this.checkFolders(item); }},// Check whether it is a folder
checkFolders(item) {
if (item.isDirectory) {
let result = this.traverseFileTree(item);
setTimeout((a)= > {
this.transferFiles(result);
}, 3 * 1000);
} else {
this.loading = false;
this.$message.info("Upload folders only");
}
},
traverseFileTree(item) {
let res = [];
var internalProces = (item, path, res) = > {
if (item.isFile) {
item.file(file= > {
file.path = path + file.name;
var newFile = new File([file], file.path, { type: file.type });
res.push(newFile);
});
} else if (item.isDirectory) {
var dirReader = item.createReader();
dirReader.readEntries(
entries= > {
for (let i = 0; i < entries.length; i++) {
internalProces(entries[i], path + item.name + "/", res); }},function(e) {
console.log(e); }); }}; internalProces(item,"", res);
return res;
},Copy the code
Because the folder may be nested relations, we do not know whether a folder inside the nested layers of folder, so it need to use recursive way, within the folder on the file for reading and then flattened out, of course to ask me if you have better way the code written here a bit rough.