tags:

views:

1218

answers:

8

Let's say we have defined a CSS class that is being applied to various elements on a page.

colourful
{
    color: #DD00DD;
    background-color: #330033;
}

People have complained about the colour, that they don't like pink/purple. So you want to give them the ability to change the style as they wish, and they can pick their favourite colours. You have a little colour-picker widget that invokes a Javascript function:

function changeColourful(colorRGB, backgroundColorRGB)
{
    // answer goes here
}

What goes in the body of that function?

The intent being that when the user picks a new colour on the colour-picker all the elements with class="colourful" will have their style changed.

A: 

Something like

function changeColourful(colorRGB, backgroundColorRGB)
 {changeColor (document, colorRGB, backgroundColorRGB)}

function changeColor (node, color, changeToColor)
{
   for(var ii = 0 ; ii < node.childNodes.length; ii++)
   {
     if(node.childNodes[ii].childNodes.length > 0)
     {
        changeColor(node.childNodes[ii], color, changeToColor);
     }

      if(node[ii].style.backgroundColor == color)
      {
        node[ii].style.backgroundColor = changeToColor;
      }

   }


}
Kevin
+4  A: 

I would actually implement this server-side; just store the user's preferred colours in their session (via cookies or whatever is nice and easy for you) and generate the CSS dynamically, i.e.

colourful {
  color: ${userPrefs.colourfulColour};
  background-color: ${userPrefs.colourfulBackgroundColour};
}

If it really suits you much better to do this via Javascript, you can manipulate the CSS using Javascript. See, for instance:

alex
I wish I could vote for this five times.
eyelidlessness
If you go sever-side, isolate the server-dependent items from the rest of the styles, so that the browser can still cache the rest of your style sheet.
Joel Coehoorn
You may also need to include a cache-breaker in the server-generated css.
Joel Coehoorn
@Joel: Or you could just set up headers correctly.
eyelidlessness
couldn't agree more - you definitely want this to be server side and in paths away from cachable/static css rules
danpickett
This is a great answer for a server-side solution. I had tried to set-up the question as a sort of general "tweaking css with javascript", which is why EndangeredMassa got the green check.Somebody should ask the question that goes with this answer.
Axel
+1  A: 

First check if document.styleSheets is defined (see @alex's response).

If not, this question should be helpful:
http://stackoverflow.com/questions/210377/get-all-elements-in-an-html-document-with-a-specific-css-class

See the link in the accepted answer and my response at the bottom.

This is only one piece of the answer. You'll still have to go and apply the new values use each element's style property.

Joel Coehoorn
+1  A: 

Quick example for a specific div/colour - which could be dynamically passed in via a function

document.getElementById('Your Div Name Here').style.background = 'white';

Or, to change the class of the specified item

document.getElementById('Your Div Name Here').classname = 'newclassname'

That's assuming you can specify the divs in this way, if not, a combination of this and the node looping solution Kevin showed should do the trick

Katy
I think .classname should be .className. I think!
Micky McQuade
+1  A: 

I don't know about manipulating the class directly, but you can effectively do the same thing. Here's an example in jQuery.

$('.colourful').css('background-color', 'purple').css('color','red');

In plain javascript, you would have to do more work.

EndangeredMassa
This is what I was looking for (though the `'purple'` and `'red'` should be `backgroundColorRGB` and `colorRGB` respectively)
Axel
I'm glad to help!The purple/red stuff was just for example purposes. You wouldn't want me to do all the work, would you? (I kid. I kid.)
EndangeredMassa
A: 
var setStyleRule = function(selector, rule) {
    var stylesheet = document.styleSheets[(document.styleSheets.length - 1)];
    if(stylesheet.addRule) {
        stylesheet.addRule(selector, rule)
    } else if(stylesheet.insertRule) {
        stylesheet.insertRule(selector + ' { ' + rule + ' }', stylesheet.cssRules.length);
    }
};
eyelidlessness
+3  A: 

jQuery:

function changeColourful(colorRGB, backgroundColorRGB)
{
    $('.colourful').css({color:colorRGB,backgroundColor:backgroundColorRGB});
}

If you wanted the changes to persist across pages you would would have to store them in a cookie and reapply the function every time.

Ken
Ill throw may weight behind you.
Brian G
A: 

I just tried using an empty <style> tag in the <head>, then filling it dynamically. Seems to work in ff3, at least.

So :

In the <head> , insert something like :

<style id="customstyle" type="text/css"></style>

Now you can use something like jquery to replace or append its content :

for replacing :

$("#customstyle").text(".colourful { color: #345 ; }");

appending :

 $("#customstyle").append(".colourful { color: #345 ; }");

If you want to save it somewhere, just grab the content :

  var csscontent =  $("#customstyle").text();

.. then you could send it back to server through ajax.

vincent