Conditional Javascript Includes
Posted by Adam Wiggins on December 03, 2007 at 04:46 PM
The Heroku toolbar floats on top of your app, providing access to some development functions.
There's quite a bit of magic to goes on to make this happen, some of which I might get into another time. But one thing we ran into recently was the matter of conditional javascript includes. We want to use Prototype and the effects libraries for the toolbar (and particularly for some of the upcoming features which will be visually complex). But since our html is being mixed in with the html from the user's app, and the user may or may not include Prototype and friends, we need a way to conditionally include these files.
There isn't a best practices sort of way to do this that I can see. But we did come up with a workable solution. Here's a static HTML proof of concept:
1 <html><body>
2
3 <!-- try commenting out the following line -->
4 <script src="prototype.js" type="text/javascript"></script>
5
6 <script type="text/javascript">
7 if (!window.Prototype)
8 {
9 document.write('<script src="prototype.js" type="text/javascript"><\/script>')
10 }
11 </script>
12
13 <div id="write_me"></div>
14
15 <script type="text/javascript">
16 $('write_me').innerHTML = "prototype is loaded"
17 </script>
18
19 </body></html>
The key here is window.Prototype. "if (Prototype)" will cause an uncatchable exception if Prototype is not defined. But since javascript globals are actually properties of the window object, we can check it there. Javascript doesn't complain at all on an access to an undefined object property.
There are some problems with this, such as the possibility of differing versions of Prototype in what the user's app has included and what the toolbar code expects. My biggest complaint with it is that it's just not that elegant. If anyone has other suggestions I'd be interested to hear them.
Comments
There are 2 comments on this post. Post yours →
Consider rebuilding the toolbar with the jQuery library. I find it to work like my brain more than Prototype happens to, but I mention it because it doesn't extend any of the builtin objects and it has a noConflict function. When you call it, jQuery releases $ and can be assigned to the variable of your choice, so you can use it alongside any other js library (including other versions of itself) without conflict.
And, you know, you could just be doing "if (typeof(Prototype) == 'undefined')" to check; typeof doesn't throw exceptions for undefined symbols (for the obvious reason that otherwise you couldn't do this).
Post a comment
Required fields in bold.