The Virtual Earth JavaScript control is not small weighing in at 217KB when compressed in Version 6.2. When you require the rich experience of Virtual Earth this size is not an issue, the control is aimed at broadband users and within a few moments of interacting with the map you can easy exceed this with the rich imagery being loaded on demand. But what if your web page only needs to show the Virtual Earth map when a user asks for it or you just want your page to load super fast? You need to load Virtual Earth on demand.
See an example here: http://www.soulsolutions.com.au/examples/VE62/loadondemand.htm (view source for full code)
In the recent release of the control, Version 6.2 a new feature was introduced to allow for a function of your choice to be called once the script was loaded. To achieve this you append the parameter onScriptLoad to the VE API url like so:
http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2&onScriptLoad=yourfunctionname
This is the key as detecting scripts being loaded across different browser is very troublesome. Lets build an example that works in Firefox, IE and even Chrome. We will make a trivial HTML page that does not reference the VE JavaScript control. It will contain a link that will run a JavaScript function to dynamically add it.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head> <title>Load Virtual Earth on Demand</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script type="text/javascript"> var loaded = false; var map = null; function onscriptload() { //get rid of our load animation and load the map document.getElementById("myMap").style.background = ""; map = new VEMap('myMap'); map.LoadMap(new VELatLong(-27.47, 153.03), 16, VEMapStyle.Hybrid); } function loadVEAPI() { if (!loaded) { loaded = true; //set a nice animated gif to show the map is loading document.getElementById("myMap").style.background = "url(ajax-loader.gif) center center no-repeat"; if (!(window.attachEvent)) { appendJS("http://dev.virtualearth.net/mapcontrol/v6.2/js/atlascompat.js"); } appendJS("http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2&onScriptLoad=onscriptload"); } } function appendJS(filename) { var fileref = document.createElement('script'); fileref.setAttribute("type", "text/javascript"); fileref.setAttribute("src", filename); document.getElementsByTagName("head")[0].appendChild(fileref); } </script> </head> <body> <p>A simple website doing its own thing, loading very fast. Click <a href="#" onclick="loadVEAPI()">here</a> to load a Virtual Earth map on demand.</p> <div id="myMap" style="position: relative; width: 800px; height: 600px;"></div> </body> </html>
The function loadVEAPI is called when the user clicks our link, using a simple flag to ensure we don’t load the script again. We first set a simple animated gif as the background for our map div, as the control is loading this provides feedback to our users. You can get your own animation from here: http://www.ajaxload.info
Important: For FireFox Virtual Earth includes a compatibility file, this file must be included before the Virtual Earth script. I found in testing this was not the case when loaded on demand. The fix is to manually load this file (if required) prior to the VE Script.
Lastly we load the Virtual Earth script passing our function name “onscriptload” to be called when it is loaded. I made a little helper function “appendJS” to neaten up the code, it creates a script element, sets the correct attributes and appends it to the head of the page.
When the script has loaded our “onscriptload” function is called as expected. We simply turn off our animation and load our Virtual Earth map as usual. Pretty simple hey?
See it in action here: http://soulsolutions.com.au/examples/VE62/loadondemand.htm
The Virtual Earth script is now cached for around 1 month so once it is loaded the first time in your browser it will load very quickly on subsequent pages. For testing you will need to clear your browser cache.