Working with different files is a common activity—although much more so on desktops or laptops than on mobile devices—so an API is available for doing this on the Web too. The File API is a fairly low-level API that allows you to get information about files and to access their contents, and there are a few higher-level APIs that I’ll mention in due course.
To access files, you can either choose them using the file input element or drag them from a folder on your system (depending on the system you use) with the Drag and Drop API, which is the approach we’ll look at here.
The dataTransfer object, which I just discussed in the previous section, contains a files child object that contains a list of all the files dropped into the drop zone. Each file has three properties—name, size, and type—and the meaning of these should be pretty obvious.
The following code example shows a function where files dropped into the drop zone will have their names listed. You do this with a for loop that runs through the files object and outputs the name property for each. Try it for yourself with the example file files.html.
target.addEventListener('drop', function (e) {
var files = e.dataTransfer.files, fileNo = files.length;
e.preventDefault();
for (i = 0; i < fileNo; i++) {
var el = document.createElement('li'), smth = document.createTextNode(files[i].name);
el.appendChild(smth);
e.currentTarget.appendChild(el);
}
}, false);
If you need more than just information about the file, the FileReader interface allows you to get the content as a text file or data URL (where relevant). The following code snippet shows a simple example using an image file as the source; the syntax is a little complex, so I’ve annotated the code and will explain it next.
target.addEventListener('drop', function (e) {
e.preventDefault();
var files = e.dataTransfer.files[0],
1 reader = new FileReader();
2 reader.addEventListener('load', function (evt) {
var img = document.createElement('img');
3 img.src = evt.target.result;
target.appendChild(img);
}, false);
4 reader.readAsDataURL(files);
5 reader.addEventListener('error', function (evt) {
console.log(evt.target.error.code)
}, false);
}, false);
In 1, a new FileReader object is created and assigned to the variable reader. To this object, a new event listener is added 2, which will fire when the file has finished loading, running a function that will create a new img element using the content of the uploaded file. The src for the img element is obtained in 3, using the result attribute of target, a child object of the event. The type of result is determined in 4 using the readAsDataURL() method, which encodes the file content as a 64-bit data string. Finally, an error event listener is added to the object in 5, which uses the code attribute of the error object of the target object of the event object (phew!) to log an error message.
Try this for yourself in file-2.html; drag an image from a folder on your system (if possible) to see it appear in the page. In addition to readAsDataURL(), a few other methods are available: readAsText() returns the content of the file as plain text, and readAsArrayBuffer() returns the content as a fixed-length data buffer (especially useful for images).
You can also use a number of APIs to go even further with files: The File Writer API allows you to modify the content of a file, and the File System API goes further still with the provision of a navigable filesystem on the user’s device. These APIs are exciting but somewhat too technical for me to go into detail in this book.