views:

29

answers:

2

I'm running the following code in jQuery to dynamically load a stylesheet. Its purpose is to allow users to load a custom stylesheet and change the look of a JavaScript widget:

this.loadStyleSheet = function(url){
    $("<link rel='stylesheet' type='text/css' />").attr("href", url).appendTo("head");
}

For a split second the screen appears jumpy, since the correct style is applied to the widget only after the dynamic stylesheet is loaded. To solve this issue, I need to know when in fact the dynamic stylsheet has finished loading.

Although this issue has been discussed before, none of the solutions apply in my case:

  1. .load() only fires in IE, not in Firefox. A cross browser solution is required. BTW, .ready() fires off before the stylesheet has finished loading.
  2. .get() only works on the same domain. The stylesheet in my case may come from any given domain.
  3. Can't query for some CSS property to change via setTimeout. The user may point to any custom stylesheet, and there is no way to know what her CSS file will contain.
  4. Waiting for a constant time after loading the stylsheet via setTimeout is obviously a bad solution. There is no way to know in advance how long it will take the stylesheet to load, if it will load at all.

Any new ideas regarding this issue? Your help is much appreciated.

A: 

To expand on my comment above if anyone else needs an answer for this:

Your Javascript would look like this:

var style = $('<style type="text/css">');
$(document).append(style);
style.load('/fetchstyle.php', { url: "http://somesite.com/style.css" }, function() {
    // The styles are loaded
});

And the fetchstyle.php script would look like this:

<?php
echo file_get_contents($_GET['url']);

Untested, but the concept should work.

mellowsoon
It would probably work, but I'd be much happier with a client side only solution. Thanks anyway.
Ido Schacham
A: 

".load() only fires in IE, not in Firefox. A cross browser solution is required. BTW, .ready() fires off before the stylesheet has finished loading."

This is very strange, .load() works for me in firefox.

"Can't query for some CSS property to change via setTimeout. The user may point to any custom stylesheet, and there is no way to know what her CSS file will contain."

Although certainly not an ideal solution, why not require a certain string to be written into the comments of the css file which you could then regex for?

Other idea: Have you considered using propertychange event?

$(body).bind('propertychange', function(){ show_my_page_after_timeout(); });

This way you could hide the page elements that may change, allow the browser to process the css then show those elements (you could even fade out and in) when the processing is completed. You can do that by having a short timeout which is cancelled if the event handler (saying css property has changed) is called again before the timeout has showed your page.

sillyMunky
.load() works for you in Firefox with the above code? It works in general, but when it comes to dynamically adding link tags to the header, it seems to break down.
Ido Schacham
sillyMunky
Well, as I mentioned shortly the whole bulk of the code I'm writing is a JavaScript widget that users will be able to embed on any site. My client doesn't want to have a custom stylesheet upload service, instead they want to grab a custom stylesheet from any given location. Does that make sense?
Ido Schacham
"JavaScript widget that users will be able to embed on any site. My client doesn't want to have a custom stylesheet upload service"It does make sense, but surely if they can add the widget then they can also add their own custom css? For example, you could load ./thewidget.css (with option to change path) then user could put their custom css wherever they want within their webroot. What situations of widget use/deployment would this not work with? How is it harder for the widget user?
sillyMunky
I was curious and so did some digging. Have you come across YQL? http://net.tutsplus.com/tutorials/javascript-ajax/quick-tip-cross-domain-ajax-request-with-yql-and-jquery/I haven't used it myself, but it definitely seems like it could solve your problem if your client insists the css must be uploadable from anywhere.Good luck! ;-)
sillyMunky
Oh, the idea is to embed some JavaScript code that a widget builder creates, like the Twitter profile widget. So the script src always points to my client's server, it isn't uploaded anywhere else. Thanks for the help and the info though!
Ido Schacham