ramblings on PHP, SQL, the web, politics, ultimate frisbee and what else is on in my life
back

How to load arbitrary html via ajax?

I have a project where we want to provide the user with numerous independent services. One service displays the current location in google maps, another one some rss feeds etc. Currently we have like 5 of them, but there will be more. These services will leverage external js files (like for google maps), js files from our server or javascript functions contained in the html returned via ajax. They could also include flash movies or some other media files. So "arbitrary html" really means anything that goes inside the <body> tag should be possible.

The javascript will likely interact with the html DOM tree returned as well. So the point is, each service should be possible to be loaded via ajax and the html around it should not have to know anything about the it. Nothing should be loaded unless the user actually wants to use the given service. Otherwise the initial page load would slow to a crawl as we keep adding new services.

Now how can this be done? There are little challenges, like MSIE not liking that you mess with elements that have not yet finished loading (like accessing proprieties in a div). This one I have traditionally solved by calling the given js function via an onload event in the <body> tag. Now since the window is already loaded this does not work anymore. I guess the best solution for this is to simply move the creation of the given <div> into the js function that wants to manipulate the given <div>.

However how do I handle other stuff, like ensuring an external js file has finished loading? I found a solution to load external js files from javascript, but that still does not ensure that the file is loaded synchronously. So I guess the only solution would be to define that every service provides a js function like "init[Service]()". At the end of the ajax request I would poll for this function via setTimeout(), once its available I will call it and this function would in turn poll of anything it needs to continue is loaded.

Is that feasible? Is there a more elegant approach? Has anyone seen something on the web I should look at? Is there a premade solution, preferably in top of prototype?

Comments



Re: How to load arbitrary html via ajax?

prototype is indeed what you want to look at.

Ajax.Updater can be used to load or replace chunks of HTML inside a page, and you can even register callback functions.

Re: How to load arbitrary html via ajax?

Jan: but that callback may be triggered before everything that was loaded is available to be messed around with. This is the problem we are facing. Google maps API is not yet loaded, some div's are not yet loaded .. in extreme cases some inline js functions are not yet loaded.

Re: How to load arbitrary html via ajax?

You should check out this page:
http://ajaxpatterns.org/On-Demand_Javascript

Re: How to load arbitrary html via ajax?

You can use YUI with the onAvailable event listener.

YUI-EXT may help to with the domHelper method (http://www.jackslocum.com/blog/2006/10/06/domhelper-create-elements-using-dom-html-fragments-or-templates/)

The yui-ext also has an updateManager which enables you to update a element content with a remote response. That combined with the onAvailable makes it possible to load on demand.

You can also define your own events with YUI and fires them when you need. All listeners subscribed to the event will get notified and then you update the element.

I hope I am making sense.

Re: How to load arbitrary html via ajax?

Hi Lukas,

Regarding the issue of making sure an external .js is finished loading. If you add .js files using DOM's appendChild() to the HEAD, you can use onreadystatechange for IE and onload for FF to make sure the new file is loaded. Check this:
http://www.phpied.com/javascript-include-ready-onload/
One of the comments has a Safari solution as well.

Re: How to load arbitrary html via ajax?

Thx for the feedback. I have now implemented a custom solution that uses polling that can be used to determine if a css or js file is loaded yet .. but it can also check if a function or DOM element is loaded as well. I hope to find some time over the weekend to blog about.