How to Open Dropped Files Using HTML5

Tweet

In my last post, How to Use HTML5 File Drag & Drop, we discovered how to use the HTML5 File API, implement drag and drop events, and retrieve file information. Today, we’ll attempt to load files on the client using JavaScript.

Why Open Local Files in JavaScript?

Uploading files from an HTML form is clunky. People often use it when transferring multi-megabyte photographs from their camera to a web server. Assuming they locate the file, the upload could take several minutes only to find it was the wrong photo, an unsupported format, or a larger file size than permitted. Until now, developers had to rely on Flash or other plugins to provide a better user experience.

Pre-processing in JavaScript offers a number of benefits:

  • Local file processing is fast.
  • Files can be analyzed to ensure they’re the correct format and lower than a specific size.
  • Files such as images can be previewed before upload.
  • It’s possible to crop or resize an image on a canvas element then upload the resulting file.

The FileReader object

FileReader forms part of the W3C File API and offers four methods to asynchronously load data from a file referenced in a File object:

  • .readAsText(File f, [encoding]): reads File f into a string. UTF-8 encoding is assumed, but the optional encoding parameter can specify a different format.
  • .readAsDataURL(File f): reads File f into an encoded data URL
  • .readAsBinaryString(File f): reads File f as a binary string
  • .readAsArrayBuffer(File f): reads File f as an ArrayBuffer object.

In the following code we’ll use the first two methods to load and display text and image files.

Opening Files Asynchronously in JavaScript

Here’s our original ParseFile() function which is passed a File object when it is selected or dropped onto the #filedrag element:


// output file information
function ParseFile(file) {

	Output(
		"<p>File information: <strong>" + file.name +
		"</strong> type: <strong>" + file.type +
		"</strong> size: <strong>" + file.size +
		"</strong> bytes</p>"
	);
	
}

Following the status update, we’ll check if we have a text file (text/plain, text/html, text/css, etc.), load it using the FileReader.readAsText() method and display the result (after escaping < and > characters):


	// display text
	if (file.type.indexOf("text") == 0) {
		var reader = new FileReader();
		reader.onload = function(e) {
			Output(
				"<p><strong>" + file.name + ":</strong></p><pre>" + 
				e.target.result.replace(/</g, "&lt;").replace(/>/g, "&gt;") +
				"</pre>"
			);
		}
		reader.readAsText(file);
	}

Similarly, we can check whether we have an image file (image/jpeg, image/gif, image/png etc.), load it into a data URL using the FileReader.readAsDataURL() method, and pass the result to the src attribute of an img tag:


	// display an image
	if (file.type.indexOf("image") == 0) {
		var reader = new FileReader();
		reader.onload = function(e) {
			Output(
				"<p><strong>" + file.name + ":</strong><br />" +
				'<img src="' + e.target.result + '" /></p>'
			);
		}
		reader.readAsDataURL(file);
	}

Please view the demonstration page in Firefox, Chrome, or Opera (no drag & drop support). You can also download the files to examine the code.

While this is useful, ultimately, we’ll need to upload our files to a web server. Stay tuned for How to Asynchronously Upload Files Using HTML5 and Ajax

Free JavaScript: Novice to Ninja Sample

Get a free 32-page chapter of JavaScript: Novice to Ninja

No Reader comments