-
addSizes.js: Snazzy automatic link file-size generation
Often in the development of a site I come across the need to display the size of a document next to the link targeting it. I also like to display the type of file the link targets, for example, when linking to pdfs, mp3s or Word documents.
These indications distinguish the 'attachment' link from a normal web link, whilst also giving the user some inkling of the time they will need to wait to view the resulting content.
So I was pretty excited when Simon bounded in from work and enthusiastically demonstrated json-head, a Google App Engine application he built on the train home.
Every file on the web, be it a web page, a text file or whatever has HTTP headers associated with it. This is meta information about the file that is sent before the actual contents of the file itself. Included in this meta information is the size of the document.
You can call json-head with JavaScript (JSONP). It takes the URL of a file on the web and performs a HEAD request against it to return the headers and not the actual content itself. The application then returns this information in JavaScript object notation (JSON) to a callback function you have written.
One of the first things that occurred to me was how this could be used to solve the problem of dynamically adding the file size to links. The resulting script I wrote is being used on this site, so before I explain how it works here's a quick demo of a pdf document and an mp3 file. For a further demo take a look at this basic file.
Using jQuery we first use CSS selectors to find all of the links with the relevant file extensions:
$('a[href$=".pdf"], a[href$=".doc"], a[href$=".mp3"], a[href$=".m4u"]')For each link, we get the type of the target by splitting the href value on '
.' and grabbing the last value. This is the file extension.jQuery neatly abstracts the faff involved in using JSONP. We pass json-head the URL of the file we want to inspect and the name of the callback function we want it to run with the results. The callback function in this case is '
?', which tells jQuery to create a random function name hooked up to the function we pass togetJSON().var url= "http://json-head.appspot.com/?url="+encodeURI(this.href)+"&callback=?"; $.getJSON(url, function(json){ /* ... */ }We can now inspect the information sent to us by json-head. If everything went OK we have the size of the file in bytes in the
Content-Lengthheader.var length = parseInt(json.headers['Content-Length'], 10);
Once we have the exact size we need to do a bit more work to get human readable file sizes. We loop through an array to find the largest unit that fits. Once the right size has been found, the script breaks out of the loop storing the unit name and the length to 1 decimal place, so we end up with something like 1.2GB.
for(var i = 0; i < units.length; i++){ var unitSize = units[i][0]; var unitText = units[i][1]; if (length >= unitSize) { length = length / unitSize; // 1 decimal place length = Math.ceil(length * 10) / 10; var lengthUnits = unitText; break; } }Now the maths is over, all that remains is to insert the results back into the dom. I am using jQuery's
.after()method but if you wanted to insert the size and type directly into the link you could change this to use.append()I also add the type of the document as a class, to allow for additional styling such as adding an icon. A future version of the script will add the content type to the link as well.
link.after(' (' + type + ' ' + length + ' ' + lengthUnits + ')'); link.addClass(type);To use this script in your site, simply include jQuery and then the addSizes script itself will do the rest of the magic.
PLEASE NOTE: this may not be 100% reliable due to App Engine being occasionally and unavoidably flakey.
UPDATE: Please see the update to addSizes.
-
dConstruct schwag
A big box of dConstruct programs arrive, all ready to be stuck with name-tags and stuffed in little plastic wallets for the attendees next week!
-
A quote from James Box
If smoking is bad for you, how come it cures salmon?
-
A quote from Snook
interestingly, IE8 officially drops support for CSS expressions.
-
A quote from Chris Wilson
For those not paying attention - IE8 beta 2 shipped today! Whoo-hoo!
