View Full Version : onload for <link> elements

03-16-2006, 03:51 PM
I have a set of scripts which rely on the ability to dynamically load css by constructing <link> elements via DOM scripting, and appending them into the page header. It works, for the most part, extremely well, but I need to be able to attach an onload function to said links.

Unfortunately, this only seems to work in IE, not in FireFox or Safari (the three being my 'target' browsers under which the whole system needs to work.)

Does anyone know of any means by which I can determine via Javascript whether such a link has finished loading? It doesn't have to be via onload if it's unsupported, but I need to be able to implement it across IE / Mozilla / Safari.

03-19-2006, 08:55 PM
I think you would have better luck if, as you say, the onload event is generally not supported for the link element, if you used document.write to write the link statement into the head of the page while it is loading instead of appending it onload as one must do with strict DOM scripting. If the document.write approach is taken, using the onload of the page will tell you when the style is loaded.

03-20-2006, 08:24 PM
There isn't a load event for link elements, but are you sure that's really what you need? Why do you ultimately need to know when the stylesheet has loaded, maybe there's another way to acheive that end result?

03-21-2006, 04:27 PM
Good questions, but, alas, I'm very sure it's what I need. There are other solutions, and I'm currently using one, but it's not ideal.

First off, the system in question is a web application, not a conventional site. For the most part, there are no pages, and it has an architecture which dynamically loads different content as and when it's needed, while unloading parts that become superfluous. All done with AJAX and Javascript, all done without reloading the page.

It's far and away the most complex piece of JS I've ever worked with, and I'm only a fraction of the way into the project.

For the most part, I don't really need to know when a css file loads - but there are a very few occasions when it becomes necessary. The particular part which inspired me to post the question is as follows: there's a facility for editing a page layout. The layout is loaded (html / css with an xml config file), the javascript editor component finds all the editable areas, and puts placeholders above them which can be clicked / dragged / resized etc. However - there are times (I'm not going to go too far into the ins and outs) when the css might be changed independently of this script - and the js will need to be alerted so it can move the placeholders.

At the moment, it monitors them via an interval, and if the base elements shift, it moves the placeholders to compensate. I don't like this though - it's inefficient, and shouldn't be necessary. So I'm looking for other options...

03-21-2006, 05:10 PM
Have the same function which loads the new css style change the locations of the elements, perhaps even via the new css.

03-21-2006, 06:04 PM
Have the same function which loads the new css style change the locations of the elements, perhaps even via the new css.

The css is loaded by putting a <link> tag into the header dynamically. The CSS will not be loaded at this point however - it's subject to the usual loading vaguaries - and the page elements won't change until it's loaded.

And yes - I could start testing for moved elements at that point only, and cancel the check when a change is detected... except that the css reload may only affect colour or other info, without affecting any positioning - so I can't reliably tell when it's complete.

Unless there's an onload equivalent (seems like we've pretty well established that there isn't) or some way of checking the <link> element to see what state it's in. I have no idea whether that's a possibility, but I haven't found anything to date.

03-21-2006, 11:38 PM
Well, you might have some success getting the style (http://www.quirksmode.org/dom/getstyles.html) (courtesy of Quirksmode.org). This shows how to test for an element's style as set in the stylesheet, not inline style.

03-22-2006, 12:06 AM
After double checking the function on Quirksmode I see that it could use a 'de-camel' routine for styles in other browsers than IE but for testing non-hyphenated/cameled style properties, it is fine and all you would need to test an element's say - color, for instance. If you need it for zIndex, I can work out a 'de-camel' reg-ex for you, but in Mozilla several hyphenated properties are simply not supported.

03-22-2006, 05:19 PM
Thanks for the answers.

Had a good long think about this. Unfortunately, it boils down to the fact that I can't easily predict what will be in these stylesheets, or how they might change. I certainly could try adding a 'dummy' element to them, with a corresponding page element & watch the style of that for changes, but that's almost certainly going to cause me more problems down the line. The only ways forward that I can think of would be:

using onload (not possible, except on ie)
monitoring the 'load' status of the element (presumably not possible)
leaving the continual monitor in place.

It was worth asking tho.

03-22-2006, 07:47 PM
Okay, well here's what I suggest - create an XMLHttpRequest and load the stylesheet with that, by making a direct GET request for the file. Once that's loaded (inside its completed readystate function), set the <link> src in the normal way .. except that since you've preloaded the file it should be loaded from cache, and hence you can consider its loading to be instantaneous.

I've had to do this before, and it works - it successfully caches the stylesheet and hence setting a link href to that value draws it from cache. But watch out for a crash bug in IE6 - if the loaded stylesheet contains @import statements then IE6 may crash when you set the HREF, but you can avoid that by first setting it to an empty string, then the stylesheet path.

But overall - if you can find a way to avoid all this, that would be better - can you do without the need to redraw the placeholders?

Does that all make sense?

03-23-2006, 12:35 AM
where is the code?

03-23-2006, 01:50 AM
I certainly could try adding a 'dummy' element to them, with a corresponding page element & watch the style of that for changes, but that's almost certainly going to cause me more problems down the line.

Before I throw in my comment, I want to mention that I like brothercake's ideas as well. My comment is that I'm not sure how adding an empty:

<span id="loaded"></span>

at the end of each page that might be involved would hurt anything. You could then change and test for its color. Neither of which would make any visual or layout impact on the pages.

03-23-2006, 10:13 AM
Brothercake's ideas are making a whole lot of sense to me also. I'll give that a whirl - thanks. Will keep you posted.

As for the <span> - it is a good idea, and I agree that it should work. It's simply that there's currently over twenty stylesheets loaded in this way, and it'll likely be well in excess of one hundred by the time the system's done - the plan is that this will constantly grow as people add new templates to the system. So you have the extra complication of keeping track of what the span style should change to each time, plus the systems for changing it, plus the need to incorporate it in all of the css, which is a potentially nasty mix of presentation vs funcionality. If that makes sense :)

Codename - sorry - I can't give a link to the pages - it's only on our internal development servers at the moment. As for the code, there's just plain too much of it to post anything useful.