views:

385

answers:

3

(I posted this on the jQuery forums but it's still awaiting moderation, so I thought I'd try my luck here since Stack Overflow is so awesome. If I get an answer I'll post it here.)

I have a couple of links on my page (inside a <div id="theme-selector">) which allow you to change the CSS stylesheets:

$('#theme-selector a').click(function(){
  var path = $(this).attr('href');
  $('head link').remove();
  $('head').append('<link type="text/css" href="'+path+'" rel="stylesheet" />');
  return false;
});

Now, after I've changed the style on the page, I want to get the new background color, using the following code (which I put after the $('head').append call):

var bgcolor = $('body').css('background-color');
alert(bgcolor); 

The problem is, I think, that it takes some time for the browser to download the new stylesheet and I sometimes get the old background color in my alert message. Is there some event I can bind that will only alert me after all the stylesheets are loaded on the page?

At the moment, all I can think of is using a setTimeout(function(){}, 5000); which isn't great, because what if it takes longer/shorter to load all the CSS on the page.

Let me know if I need to clarify anything and I can provide more code.

A: 

You could simply keep on checking if the background colour is still the same, and then do your thing if ever it changes.

oldbackground=getbackground()
function checkbackground(){
    if(oldbackground!=getbackground()){
        oldbackground=getbackground()
        //Do your thing
    }
}
setInterval(checkbackground,100)
eBusiness
+4  A: 

Rather than creating a new link element and appending it to the head, you could retrieve the contents of the stylesheet with an AJAX call, and insert it into an inline style block. That way, you can use jQuery's 'complete' callback to fire off your check.

$('#theme-selector a').click(function(){
  var path = $(this).attr('href');
  $.get(path, function(response){
   //Check if the user theme element is in place - if not, create it.
   if (!$('#userTheme').length) $('head').append('<style id="userTheme"></style>');

   //populate the theme element with the new style (replace the old one if necessary)
   $('#userTheme').text(response);

  //Check whatever you want about the new style:
  alert($('body').css('background-color'));
  });
});

I haven't actually tested this code, so there may be some syntax-y errors, but the logic should be sound enough.

Beejamin
Yea, you left out a couple of brackets, but it works like a charm. Thanks!
Dave
I updated the code snippet so it will work now!
Beejamin
+3  A: 

The load event can be watched for any element associated with a url, does this not work for you when loading the css stylesheet? http://api.jquery.com/load-event/

Try something like this:

var path = $(this).attr('href');
$('head link').remove();
var styleSheet = $('<link type="text/css" href="'+path+'" rel="stylesheet" />');
styleSheet.load(function(){alert("Loaded");});
$('head').append(styleSheet);

Edit: As pointed out below this only works in IE, who would have thought?

Michael
Thanks, I got this working with a slight modification... $('head').append('<link id="ss1" type="text/css" href="'+path+'" rel="stylesheet" />'); $('#ss1').load(function(){alert("Loaded");});Only problem is, this only seems to work on IE. See http://www.daniweb.com/forums/thread257850.html. I couldn't get this to work in Firefox, etc either.
Dave
Theoretically it should have worked ;)
Michael