Recently I've been doing quite a lot of work with Bing Maps. Not every page on the site requires the map API so we've been attempting to use require.js, which we already have, to maintain that dependancy.
As usual it's more complicated than we'd hoped. Bing Maps provides a callback hook that we can use with the async plugin of require.js, however the callback fires before the maps are actually ready to use. The Microsoft object is defined but the Maps and Location objects are not. This led us to implement polling to check for these properties before resolving a deferred.
Why this is bad: The require module is now returning a promise rather than the maps declaration that you might expect to be returned. In practice this is manageable because by using the deferred our code can continue regardless of the Maps loaded state.
I've created a sample Gist of how this can work, although for production you may also want to handle the failure case and reject the deferred.
A very long time ago, 2010 maybe, I was asked to build a site with an "app like feel", which seemed to mean "we don't like page refreshes". At the time we used AJAX, we had control over the HTML generation so could strip everything but the HTML out server-side. More recently however I was asked to do a similar thing, but without the ability to change the skeleton markup.
The primary issue with adding a full set of markup into an existing page is that the script tags will automatically be executed. The jQuery load method gets around this by removing the script tags from the HTML string, but everything else is added to the document. If you specify an ID then jQuery will add this HTML into the DOM and then select the element.
It's a very useful function but can we do the same thing with an iFrame and are there any advantages in doing so?
Commonly we use iFrames for showing content from another domain. This commonly limits the communication between the parent and child pages due to the cross-domain policies. However pages on the same domain don't have that limitation, we can access the content of the child frame directly from the parent page.
frame = document.getElementsByTagName('iframe');
innerDoc = frame.contentDocument || frame.contentWindow.document;
// example select in the child frame
elem = innerDoc.getElementById('anElementsId');
But why might we want to use an iFrame rather than jQuery.load or a similar AJAX method? To my mind there are very few reasons to do this but biggest benefit is that you're able to to run more complex and multiple selects rather than being limited to the ID selector.
In this method the child frame will load fully, all scripts will execute. The analytics scripts will run and the page would be rendered fully. This makes it more expensive in bandwidth and memory so remove the iFrames when you're done (watch out for leaks) and this memory should be released...
I've recently been contributing to a set of front-end standards for Sapient, you can see the results at bp.sapient-lab.com. It's a working document that will hopefully evolve over time.
- Namespace your code with a closure
- Pass libraries into your closure to ensure your references
- Use the right pattern for your code, if it's not an object don't write it as one
- Write comments!