Force javascript to run AFTER a DotNetNuke page is fully loaded

Location: BlogsAll BlogsDNN Development    
Posted by: mamlin 4/2/2008 4:06 PM

So you want to insert a bit of javascript on your DNN page to perform some function that you probably should code into a module but you know you can implement more quickly by dropping script into a Text/HTML module (or in the Header/Footer of any module's Advanced Settings).  The problem is, your script fires at the wrong time -- before the page is fully loaded.  Here's a way to insure your script always waits until the DNN page is loaded...

The solution relies on the premise of "javascript closure".  That topic is too big to tackle in this post but you can read up on it here:  http://www.jibbering.com/faq/faq_notes/closures.html

In short, closure lets you begin execution of a function that is not fully bound until the page is fully loaded, therefore the function cannot actually execute until the page is fully loaded.  The function gets queued during page load and does not execute until page load is complete.  Cool, huh?

Just gimmie the solution
Sorry, I forgot -- you're here because you probably wanted to implement something FAST without stopping to code a module.  Ok, here's the solution with thanks to Simon Willison (http://simonwillison.net/).  Simon coded the short solution we'll use.

Our solution is to use a helper function to call our target javascript code.  The helper function acts as a wrapper to take advantange of javascript's closure feature.  Our target code will be an uber-simple function to open an alert box that says "Page has loaded":

Now on to our "closure" helper function.  Again, "closure" is a big topic so I won't explain the function other than how to use it.  Follow my previous link to read all about identifier resolution, execution context and scope chains and the following function might begin to make sense.

Here's the helper function courtesy of Simon Willison:

function addLoadEvent(func)
{ var oldonload = window.onload;
  if (typeof window.onload != 'function')
  { window.onload = func; }
  else
  { window.onload = function()
    { oldonload();
      func();
    }
  }
}

To use the helper, call it with the name of our target function:

addLoadEvent(msgPgLoaded);

Now our 'msgPgLoaded' function will not fire until the page is fully loaded.  Perfect!

Call addLoadEvent with inline script
For our simple example of an alert box we could have also called our helper function and passed the actual code we wanted to execute.  That would save us from having to include a separate target function.  Here's the same task accomplished by passing code in the addLoadEvent call:

addLoadEvent(function() { alert('Page has loaded') });

Real-world example
How is this closure ability useful to the common DNN coder?  I'll give you the very example that led me to implement my first closure helper function in a DotNetNuke environment:

A client required a "dashboard" view of several unreleated groups of data.  Some data was culled from input form responses while other data was queried from various DNN database tables.  In all, a very busy page with a lot of data.  The customer was somewhat overwhelmed by the resulting amount of data but insisted on having everything on one page.  We determined that a single reporting page would be sufficient IF the customer were given a simple pop-up box alert when certain data met certain criteria.

The issue we now faced was how to quickly deliver the requested alert functionality consistently across multiple module types (including some 3rd-party modules).  Added to this, some of the requested alert logic required a comparison of results across multiple modules.

Since we're talking about javascript you can guess that our answer was to write a small javascript parser to compare the various modules' output data and pop alerts when appropriate.  We placed our code inside a hidden Text/HTML module at the bottom of our reporting page.  This worked well until we re-arranged the positioning of modules on the page -- suddenly our lovely javascript solution began popping alerts before data was loaded!  Because of our module re-arrangement DNN was loading our hidden script module before some of the data reporting modules it depended on.

We could have just re-positioned our hidden script module until it was the last module loaded but we wanted a solution that could survive a simple module move or a skin change.  The eventual answer was to employ the same closure helper function outlined above.

Last word:  Beware multiple addLoadEvent calls
Oooh you knew this was coming, didn't you?  As enticing as this solution is, coders still must be careful when making more than one addLoadEvent call on a page.  Why?  Because some  functions may take actions that prevent other functions from executing.  A classic example is having two functions you want to execute back-to-back.  If function #1 happens to result in a postback then function #2 never has a chance to execute!  Be mindful of all the possible functional paths your closure-enabled scripts can take.

Permalink |  Trackback

Comments (10)   Add Comment
Re: Force javascript to run AFTER a DotNetNuke page is fully loaded    By Patrick on 4/13/2009 8:58 AM
You just saved my butt. A client of mine has been having really ugly problems with their Flash movies loading before the page on IE. I tried everything, including brute-force solutions such as adding a 3 second delay on the movies. That was tacky and sometimes it didn't work. As you already know, just using document.onload doesn't work either. Using your code along with SWFObject did the trick. You're my hero.

Re: Force javascript to run AFTER a DotNetNuke page is fully loaded    By mamlin on 4/13/2009 1:18 PM
Patrick- This code (credit again to Simon Willison) has saved me numerous times as well. I find that it is an extremely handy tool for DNN in cases where writing a custom module is overkill. Good to hear that you employed the javascript "SWFObject" method of creating a Flash instance rather than the older "object embed" method -- too many people are still using the older method (which can cause them other headaches). Thanks for the feedback!

Re: Force javascript to run AFTER a DotNetNuke page is fully loaded    By Rob on 6/30/2009 12:52 PM
Patrick, What was the full code you used to delay the flash movies. New to this but need a quick answer with full coding.

Re: Force javascript to run AFTER a DotNetNuke page is fully loaded    By mamlin on 6/30/2009 12:59 PM
Rob- I hope Patrick does return, see your question and post an example of his code. Unfortunately, since there is no "notify me by email" option when comments are posted, I doubt Patrick will happen to return to this particular posting, re-read these comments and see your question. I think your need is a common one, though -- I'll consider making my next "technical" blog posting an example of adding a Flash movie using the javascript "closure" technique. I'm swapped with work at the moment, though, so it may be a while (two weeks or more) before my next posting...

Re: Force javascript to run AFTER a DotNetNuke page is fully loaded    By Matt Abron on 9/10/2009 11:13 PM
YEA,I sure could use this fir SWF load...any closer ideas in implementation....

Re: Force javascript to run AFTER a DotNetNuke page is fully loaded    By mamlin on 9/10/2009 11:21 PM
Matt- Actually, yes...I finally sat down and tested this approach with loading Flash. It works perfectly when using the "SWFObject.embedSWF" function (must include the Google "swfobject.js" library). Flash files wait until the page is fully loaded (including graphics) before attempting to load Flash. A full example of doing this will be one of my next blog posts. In the meantime, you can try things out yourself using the swfobject.js library here: http://code.google.com/p/swfobject/

Hey Thanks for the Lead!!!    By Matt Abron on 9/11/2009 9:34 AM
I will look into swfobject.js as i am familiar with it terms of loading my Flash .... I am still a little in the dark as how to implement the code you have outlined above as i am more if a designer ... But i will read up and try to get a working start and possibly ring back in with a question, or 2! Thanks again for a great resource ... BTW: many people out there are looking for a solid easy to implement solution so I bet your blog post on this will be very popular!! Kindly, Matt

Re: Force javascript to run AFTER a DotNetNuke page is fully loaded    By mamlin on 9/11/2009 9:38 AM
Matt- In a nutshell, place the "SWFObject.embedSWF" line within a javascript funciton and use the "addLoadEvent" to call that function. It's super-easy once you know how. I'll try to bang out a post on this in the next few days and include a downloadable ZIP of a few sample files. Thanks for the comments!

Re: Force javascript to run AFTER a DotNetNuke page is fully loaded    By Chris on 11/27/2009 7:47 AM
This has been a great help, thanks :)

Re: Force javascript to run AFTER a DotNetNuke page is fully loaded    By Paul on 3/19/2010 9:43 PM
Hi, Just wanted to say thank you so much for posting this. I had a DNN Page which was injecting javascript into the page to redirect to another page and it wouldn't work until I put a Javascript. Then I realized it was a timing problem. So, I changed the injected Javascript to call the addLoadEvent function and it works in Firefox just fine, now to get it working in IE 8 .... Thanks, Paul


Your name:
Title:
Comment:
Security Code
Enter the code shown above in the box below
Add Comment   Cancel 
You are here:  
 
>> Back to the top of the blog list...

 
        account   advanced   blog   click   cloud   code   content   create   data   different   events   example   feature   file   files   free   function   good   google   just   line   list   module   modules   need   option   page   pages   query   results   role   roles   script   search   select   settings   simple   site   skin   solution   step   tags   terms   time   user   users   value   version   want  
Minimize Google AJAX Search
 
Search ES:  
This is an example of a Google AJAX Search with asynchronous search execution for two searches.  See our blog series, 'Add Google AJAX Search to your DNN skin' for info and sample code.
 
     
Minimize Get the T-Shirt
 
Shirts by Eguana Solutions
(Be cool like us!)
 
     
Minimize Most-Commented Blogs
 
 
     

Minimize Looking for more info?
 

There are tons of helpful
posts from Eguana Solutions 
on the DotNetNuke.com forums.
  
 
Click HERE to see our posts.

 
     
Minimize Modules for Sale
 

Looking for Eguana's modules? 
We're still working on them!
  

Until ours are ready to dazzle and
amaze, you'll have to make do with
the thousands of modules already
available on SnowCovered.

 
     
Minimize Favorite Modules
 

There are many great DNN modules.
A few we highly recommend are:
 
Dynamic Registration
Total control over the user signup process.  Create custom forms, execute your own SQL, use the integrated payment processing features to assign user roles, validate USERNAMEs via AJAX and much more.  Very cool.
 
URL Master
Change to friendly URLs that really ARE friendly.  Add keywords into your page URLs for better SEO.  Create 301 redirects for individual pages.  Force visitors (and search bots) to a single domain (i.e., make everyone use the "www" version of your site's URL or vice versa).  One of the single best upgrades for any DNN site.
 
Document Exchange 5 (DMX5)
Drag-and-drop from Windows Explorer directly into the DMX file manager!  File versioning, file and folder moderation, extend user permissions down to the file level (for user groups and even for individual users).  Infinite file and file info presentation options via custom display templates.  Store files locally or remotely via UNC (i.e., can securely store files somewhere besides your web server).  Much more.
 
XMOD by DNNDev
Rock-solid form module for data collection.  From simple feedback / email forms to complex, multi-part tabbed forms.  XMOD is different from other form modules because XMOD does not create a new database table for every new form definition -- an important feature if you plan to create dozens or hundreds of forms over the life of your DNN instance!  Excellent support from the developer and an active community around this module.
 
If you desire your form module to create a new DB table for each new form definition, a great alternative to XMOD is the Dynamic Forms module from DataSprings.  Dynamic Forms offers direct DB access beyond that found in XMOD as well as an easy drag-and-drop form builder option to help you get up and running very quickly.

 
     

Login