Bing Maps V7 Control Lazy Loader

Recently on the Bing Maps forums it was brought up that their was no built in way to lazy load the Bing Maps V7 map control. When Bing Maps V6 was first released this functionality did not exist either but an update added the ability to add a name of a callback function as a query string parameter to the map control URL which would then be called when the map control has finished loading. The parameter name is onScriptLoad, trying this with V7 does not seem to work so

What is Lazy Loading and Why would you want to do it. Lazy loading is when you load in resources only when they needed at some point in time rather than loading it when something loads. For instance, if you have a simple web page with two tabs on it. The first tab might show a list of locations as a table and may be the default view users see after doing a search. In this situation there is no need to load the map control when the web page loads. You only need to load the map control if the user clicks the map tab. The tricky part is that not only do you need to load the map control then load an instance of the map but you need to wait until the map control is fully loaded before you create an instance of the map, otherwise an error will occur.

In Bing Maps V6.3 we simply need to add something like this “&onScriptLoad=GetMap” to the end of the map control URL to call our callback function. Trying the onScriptLoad parameter with the V7 control did not seem to work, this is were this blog post comes in.

Since we really just need for the Microsoft.Maps.Map object to be loaded before we load a map we can create some rather simple code to lazy loading the map control. I created a class called LazyMapLoader that not only loads the map control and then calls a callback when it is done, but it also has a useful method called IsLoaded which lets us know if the map control is loaded already.

var LazyMapLoader = new function(){
    var _callback = null, _isLoading = false;

    /******************
 * Private Methods
 ******************/
    function loadJSFile(file)
    {
        var script = document.createElement("script");
        script.setAttribute("type", "text/javascript");
        script.setAttribute("src", file);
        document.body.appendChild(script);
    }

    function isLoaded(){
        return typeof(Microsoft) != 'undefined'
            && typeof(Microsoft.Maps) != 'undefined'
            && typeof(Microsoft.Maps.Map) != 'undefined';
    }

    /******************
 * Public Methods
 ******************/

    this.LoadMapControl = function(culture, callback){
        var loaded = isLoaded();
        if(!_isLoading && !loaded){
            _callback = callback;
            _isLoading = true;

            if(culture == null || culture == ''){
                culture = 'en-US';
            }

            loadJSFile("http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0&mkt=" + culture);
            setTimeout('LazyMapLoader.__LoadCallback();', 100);
        }else if(loaded){
            _callback();
        }
    };

    this.IsLoaded = function(){
        return isLoaded();
    };

    this.__LoadCallback = function(){
        if(isLoaded()){
            _callback();
            _isLoading = false;
        }else{
            setTimeout('LazyMapLoader.__LoadCallback();', 100);
        }
    };
};

We can then create a simple web page that loads the map control and a map with the click of a button. Take for example this web page:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
   <head>
      <title>Lazy Map Loader</title>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

      <script type="text/javascript" src="BM.LazyLoader.js"></script>

      <script type="text/javascript">
        var map = null;         

        function GetMap()
        {
            // Initialize the map
            map = new Microsoft.Maps.Map(document.getElementById("myMap"),
                     {credentials:"YOUR_BING_MAPS_KEY"});
        }

        function LoadMapControl(){
            if(!LazyMapLoader.IsLoaded())
            {
                LazyMapLoader.LoadMapControl('en-US',GetMap);
            }else if(map == null){
                GetMap();
            }
        }
      </script>
   </head>
   <body>
    <input type="button" onclick="LoadMapControl()" value="LoadMap"/>
    <div id='myMap' style="position:relative; width:800px; height:600px;"></div>
   </body>
</html>

And there you go, a simple and reusable class for lazy loading the Bing Maps V7 map control. You can download the complete source code here.

Advertisements

One thought on “Bing Maps V7 Control Lazy Loader

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s