rob cherny.com

About

My name is Rob Cherny and I'm a professional Web Developer with 16 years of experience creating Web sites and Web-based applications. This site is where I write about my work, and random other things...

Learn More

Loading...

Close Tab

Web Development

DomLoaded Object Literal Updated

Updates and New Info, HTTPS Issue Resolved (sorta)

This is an update and some new information on my DomLoaded object literal, based on Dean's and Matthias' code for solving the "onload" problem: that is, can we fire off some events when the document object model has loaded into the browser, but before all binaries and other dependencies have loaded? The idea is, speed up the page.

Once again, we only have to even bother with this because browser support for the DOM Events and DOMContentLoaded is sub-par. Mozilla Firefox and Opera 9 both support it, but others... not so much.

There's also some more caveats and research being done on when this can and can't be used... appears it's not the perfect solution I thought it was. Bummer.

I have however added code to make it work in most situations, although it's a kludge. Read on.

Updates

So per many a request I've updated my DomLoaded object literal script to be able to execute multiple times based on multiple calls.

This is useful from the perspective of larger systems where there are many things which need to be set up when a page or series of pages load. Say for instance there were some menus for an entire site which needed to be enabled but then for a specific location in the site there was some drag n' drop action which needed to be initialized? Well, now the script will do it.

In the past using the script you had to queue up all your scripts into a single init() script, all called by the single statement:

  1. DomLoaded.load("init");

Now, with the new version of the script, you can do this multiple times:

  1. DomLoaded.load("setUpMenu");
  2. DomLoaded.load("setUpDragger");
  3. DomLoaded.load(function() {
  4.     alert('foo-bar');
  5. });

Nice. I can't take the credit, there's others out there that have done a lot with the onload code as well, and many others which added multiple calls.

At any rate, I've updated the demo script and JavaScript source online here to include the ability to be called multiple times, as well as updating the browser test for the Webkit/KHTML browser to a better test.

New Info and HTTPS Issue Resolved (sorta)

Further testing finds that the technique doesn't work fully under HTTPS in Internet Explorer. Because the script relies on:

  1. defer src=javascript:void(0)

... the javascript:void(0) is considered insecure content, so IE will toss one of those Secure/Insecure content alert errors that are so annoying. So bottom line, in an HTTPS environment, the best we still have is Dean's original solution, which relied on an external file for Internet Explorer.

Sigh. Browser differences suck.

The only solution for now I could think of was to combine Dean's original solution and the new solution into one, which mean's there's a second file needed for IE.

How does it work? I've added support in the IE version to detect the protocol and then fire off the appropriate portion:

  1. if (location.protocol == "http:") { (inline) }
  2. else if (location.protocol == "https:") { (external) }

So there we have it. Let me know if it blows up for you.

Links of Interest

Just some additional reading:

Update: Thank's to Matthias I've updated the script, again. This is way cleaner and no extra file is needed. Thanks Matthias.

Update 2: Fixed some issues with the way the script was implemented for IE, noted in some comments, either here or on one of the other posts about this script.

Jul 3, 01:04 PM in Web Development (filed under JavaScript)

  1. Matthias Miller    Jul 3, 01:20 PM    #

    So the src=”https:///” trick didn’t work for you?

  2. Matthias Miller    Jul 3, 01:23 PM    #

    You might also want to remove extra alerts from your script.

  3. rob    Jul 3, 01:29 PM    #

    I just saw that. Thanks. Was just updating my post as you were typing, I think :)

    Extra alerts were in there because I was testing live.

    What are the odds you’d be online at the same exact moment…

    Thanks again. I'm going to revisit with the protocol detection and no extra script -- using "https:///".

  4. Matthias Miller    Jul 3, 03:05 PM    #

    I’m not sure I understand why you need protocol detection

  5. rob    Jul 3, 03:35 PM    #

    Matthias: I incorrectly assumed that in a non-secure environment you’d still use javascript:void.

    I was thinking you’d get the error about secure/non-secure because the script was referencing the https:/// and the page was under http.

    I just tested it and I guess you don’t. Sigh. I’m a bit surprised. For IE, bug, or feature?

    Nevermind. I’m having a heck of a day…

  6. Matthias Miller    Jul 3, 04:48 PM    #

    The reason that you can access HTTPS scripts from an HTTP page is because you’re upgrading security instead of downgrading.

    It doesn’t really matter that you’re mixing content because the main page is known to be non-secure. However, pulling non-secure content into a secure page would allow the page to be compromised because the script is susceptible to attack.

    The warning doesn’t accurately describe the problem, so call it a bug. It’s going away in IE7—non-secure items simply won’t load in a secure environment.

  7. rob    Jul 3, 09:11 PM    #

    Matthias—yes, yes, this all makes perfect sense of course.

    Thanks for all the help!

  8. Alistair Potts    Jul 6, 10:18 AM    #

    This solution for https works, tested on IE7, IE6 and IE5.5 over 80 and 443, firing correctly onreadystatechange:

    src=https:javascript:false

    https:/// was a suggested solution, but caused errors on https pages (although OK on http).

  9. rob    Jul 6, 06:59 PM    #

    @Alistair- under what conditions testing and in what browsers were you seeing the errors with “https:///”? It was my understanding that it worked and this latest version of my script does in fact use that…

    So you’re suggesting to use the following as the source for the SCRIPT element in https?

    “https:javascript:false”

    Please let me know…

  10. Alistair Potts    Jul 6, 07:24 PM    #

    The triple-slash does fail in IE7b3 – but my solution generates a bogus http request. After some faffing around (and input from Out of Hanwell) a lowest-byte solution is:

    src=//0

    I’ve posted a test page here:
    https://www.partyark.co.uk/html/ie7b3success.asp

    Alistair

  11. rob    Jul 6, 10:43 PM    #

    Hey Alistair, very cool, thanks for the update.

    What’s with the hang though? I haven’t had a chance to pick it apart, but my IE seems to hang while doing the src=//0 request? Are you seeing that, or is it supposed to based on something the scripts are doing (as I said, haven’t picked it apart yet)... with the defer in there I thought it wouldn’t…

  12. Alistiar Potts    Jul 7, 05:36 AM    #

    Do you mean the ‘hang’ while loading the test page? That’s a deliberate hang in the server code to ensure the DOM takes a few seconds to completely load. Otherwise things happen so quickly that you can’t tell if the defer is working properly.

    The hang’s not related to the //0 ‘request’. Internally, IE returns HTTP 502 Connection Failed. //[] (Hanwell’s suggestion) returns 400 Bad Request, either of which is fine. But src=//: seems to generate no request at all, even internally (I’m using Microsoft’s ‘Fiddler’ HTTP debugging proxy, and ieHTTPHeaders) so maybe that’s the best solution.

    I’ve updated the page.

    A

  13. rob    Jul 7, 09:25 AM    #

    Ah, ok, no wonder—when I peaked under the hood I still couldn’t figure out where it was happening. So your ASP was doing that. Excellent. Thanks for the information. This is great stuff!

  14. Paul    Jul 13, 08:07 PM    #

    Perhaps someone already tried this in another browser and it failed, but I just used src=’’ and it worked in IE 6, threw no security error, and definitely used the cc code b/c I checked with an alert. Let me know if this won’t work for some other reason, but for now it’s working fine.

  15. Alistair Potts    Jul 17, 06:57 PM    #

    Paul – using src=’’ will not trigger the ‘defer’ bit of the script. You need to set up a test page with a very slow loading time to test it correctly.

  16. Jakob Kruse    Jul 27, 07:02 AM    #

    Isn’t there an error in the script on the line that reads:

    if (location.protocol == “https:”) proto = “src=//0”;

    It would seem that you get something like src=”src=//0” from this.

  17. rob    Jul 28, 11:01 AM    #

    uh… yeah. Sorry about that. I’ll fix when I get some time…

  18. Diego Perini    Jul 31, 11:29 AM    #

    Rob,
    your DOMLoaded may also benefit from my latest findings on the document.activeElement and document.fileSize properties.

    There is an event called “onactivate” also related to the document.activeElement.

    These are Internet Explorer only properties that I hope will allow us to swapout the current IE tricks we are using. If you write me I can send the latest test case and my DOMComplete for you to try.

    Read more about original MS documentation and other interesting links in Dean blog.

    I also update “DOMComplete” on my test site . It will be the only method that can fire before images are loaded on older browser like FF < 1.5 and Opera 7/8.

    Hope it will improve our scripts capabilities on the “onload” problem.

    Diego

  19. Diego Perini    Aug 6, 11:15 AM    #

    Rob, at the moment, on Internet Explorer I discarded the “onactivate” event and the “document.activeElement” property in favor of polling for the “document.fileSize” property.

    I have updated the current DOMComplete on my test site for you to try, there is a test case in HTML and in PHP with a forced 5 seconds “delay” in the output. I now get the same behavior of DOMContentLoad in all 5 browsers I can test on Linux and Windows.

    Hope to get your feedback when you are back to this…

  20. wesley    Aug 13, 11:49 AM    #

    Can you tell me what exactly does not work with this solution?

    “There’s also some more caveats and research being done on when this can and can’t be used… appears it’s not the perfect solution I thought it was. Bummer.”

  21. rob    Aug 15, 11:17 AM    #

    Wesley, it really seems to work just fine as long as you fix the lines of script like:

    if (location.protocol == “https:”) proto = “src=//0”;

    and…

    ...defer src=” + proto…

    where the “src” is in there twice.

    Be sure to read the other articles I’ve linked to, and my updated article.

    Diego’s script looks interesting too, but with my move I just haven’t had time to pick it apart yet.

    I plan on posting/updating as soon as I can. Sorry for the neglect.

  22. brad    Aug 24, 01:55 PM    #

    Can’t you just leave out the src attribute entirely? Seems to me that is the lowest-byte solution.

  23. rob    Oct 10, 11:03 AM    #

    Just not sure that it works without it. Did you test that? I’d assumed with the others doing some of the testing and coming up with solutions there, they would have tested that. I can try it later, but don’t have time just now.

  24. Giles    Jun 8, 01:29 PM    #

    The one thing I can’t find in this object is support for handlers that run after all content is loaded – which can be useful when, for example, you have a function which swaps PNGs for IE6 compatible elements in the manner of the PNGfix.js.

    See a comment on Dean Edwards blog here – #92 and #93: http://dean.edwards.name/weblog/2006/06/again/#comment6825

    It would be great to be able to attach events which run after all content is loaded in the manner of window.onload, as well as events which run when the DOM is loaded.

  25. rob    Jun 11, 10:49 AM    #

    So Giles, just so I’m sure I have this straight, you want to have the DOM Loaded object to fire when the DOM is loaded, and you’d like it to support when the Window onload is fired? Hmmmm, I had never actually considered that.

    The PNG issue is one I haven’t actually run across, but may be a real valid point. I’ve never had both in the same page, I don’t think, but I’m only starting to use PNG’s more and more.

    At this point, I guess you’ll have to either hack it in or use a different script for that portion. I understand it’s less than ideal managing all that in different places…

    This is sorely in need of updates, I haven’t had the time… thanks for commenting however.

  26. Tercüme bürosu    Oct 30, 01:02 PM    #

    You might also want to remove extra alerts from your script…

  27. rob    Nov 2, 10:19 AM    #

    I only see alerts() in the demo script, not in the core library. They’re there to help with demonstrating the load/calling order, that’s all…

    Are there more that I’m not seeing?

    Regardless, the script needs some updates…

commenting closed for this article

In This Section