Darcy ClarkeDevelopment / Design / UX

Toggle Main Navigation

Jul 15, 2011

Getting a clean document or window Object in JavaScript

Posted in "development"


Most JavaScript libraries and plugins have now implemented a form of protection against carless remapping of native methods. Protoype.js itself used to do this kind remapping/modification, which they've now changed. That said, there's still a very real possibility, as a library or plugin, that your script will be run in an environment not carefully maintained by other scripts.

So, how do I protect my code?

I was actually asked this question by Anton Kovalyov (of the awesome company Disqus). It's among a list of many formulated to help with developer interviews (this list was created by some savy Front End / JavaScript Devs). To be honest, I was caught off guard that I had been right by my initial thoughts to its answer. Of course, I said nothing to Anton though (smooth). The Answer: The only true way to make sure you're working with a clean instance of either the window or document objects is to embed an <iframe> and nab that clean, untampered version of both. Pretty straightforward, but if you haven't had the need to do something like this before it may not have come to you as easily.

Note: You may have also thought that you could embed your plugin or library before any other scripts but you can't be reassured users of your script will do this (something I thought of as well).

A very rudimentary example of the kind of code would be:

(function(){
    var iframe = document.createElement('iframe');
    iframe.style.display = "none";
    iframe = document.body.appendChild(iframe);
    var _window = iframe.contentWindow,
         _document = iframe.contentDocument || iframe.contentWindow.document ;
    document.body.removeChild(iframe);
})();

jQuery does something very similar in order to retrieve the contents of an iframe in the method .contents(). The real magic of an iframe element object is its .contentWindow property. This is where the iframe's window and, subsequent, document objects are stored. Using these, we can store clean copies of both to be used within our code.

<p class="note">Note: Some browsers implement .contentDocument, the iframe's document object, directly on the iframe object and not nested under the .contentWindow (or window object). In our example, we've added a check for this much like jQuerys/the accepted implementation.

I highly recommend the use of this, or similar, code if you're a plugin author that relies on a stable environment (which I think most would).