Forum Moderators: open

Message Too Old, No Replies

Edit CurrentStyle in Firefox?

Please read this carefully.

         

vol7ron

7:12 pm on May 19, 2010 (gmt 0)

10+ Year Member



Please read this carefully.

Given:
[pre]
.default{display:none;}
<div id="foo" class="default">test</test>[/pre]


Retrieving the computed/current style of an element:
[pre]
var obj = document.getElementById("foo");
var prop_value = (document.defaultView)
? document.defaultView.getComputedStyle(obj,null).getPropertyValue('display')
: obj.currentStyle['display'];
[/pre]

The question is how to set the current style?

What won't work:
obj.style.display='';
obj.style.setAttribute('display','');

It's true that you could do something like obj.style.display='block', but doing obj.style.display='' should set the property to the object's default setting ('block' for divs and 'inline' for spans). Though, it seems that it first sets the element to the class's default, which in this case display would be set to 'none'.

I want to be able to set the current/computed style directly to '' because I want the element to result to it's object's default value, not the class's default value.

Looking at code in the past, I never had to do this, all I did was create two separate classes, which I switched between. Because I like trying new things, I was curious if anyone knows of a setComputedStyle, or similar.

Thanks,
vol7ron

Fotiman

8:22 pm on May 19, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I think you have a typo in your example (</test> should be </div>)

As for the display property [w3.org], the spec does not define what it means to set display to ''. In other words, doing obj.style.display = '' is attempting to set the display property to an invalid value, and as such the inline style rule will not be set on the element. You've not removed the class assignment on that object, so the rule defined in the default class still applies. In other words, your assumption that setting obj.style.display = '' should set the property to the object's default setting is an incorrect assumption. Setting obj.style.display = '' is essentially the same as doing obj.style.display = 'someinvalidvaluethatwillbeignored'.

Also note that the initial value for display is 'inline', even for divs and such.
Note that although the initial value of 'display' is 'inline', rules in the user agent's default style sheet may override this value


Now, the only alternative that I can see (assuming you're not going to swap classes) would be to do something like:


switch (obj.tagName) {
case 'DIV':
case 'P':
displayValue = 'block';
break;
case 'SPAN':
displayValue = 'inline';
break;
}
obj.style.display = displayValue;


Note, that is a VERY incomplete example, only meant to give you an idea.

Alternatively, you don't actually need to "switch" between classes, you just need to remove the class that is setting display to none, in which case the browser default will be used. This is probably the best solution.

Hope that helps.

vol7ron

8:34 pm on May 19, 2010 (gmt 0)

10+ Year Member



Because it seems the browser cascades stylesheet values, does anyone know how to retrieve the original style sheet setting?

So instead of doing obj.style.display = '', something like the following could be done instead:
obj.style.display = obj.style.display.defaultValue;
- or -
obj.style.display = document.styleSheets[0][obj.tagName].style.display;



@fotiman:
(1) yes I did mean </div>, not </test> - you, my friend, read carefully :)

(2) I think I was under the assumption that display='' sets the value to a null string, which is unlike display='SomeInvalidValue', even so, it still removes the current DOM method in place (set by obj.style.display='block' || 'none'), which is what I want.

(3) Unfortunately, I'm trying to write something a little more robust, that is cross-element. I gave DIV/SPAN as the example elements, but it could be for any block or inline element, so a switch is not ideal.

(4) As for the suggestion to drop, rather than change the class. I was using a class made up of several style properties. Therefore, I couldn't just drop the whole class, I had to replace it with a similar one, just with a difference in that one property. In this case, I'm trying to avoid changing any of the class setting. Many elements rely on several different classes, if I change the document's stylesheet for that class, then it might affect other elements. The effect could be catastrophic :)

The ideal solution would be to have a way to search the browser's default stylesheet (which I tried to explain above), for that tag.

I don't know the DOM tree for it and it's too hard to find in firebug. I need something like document.[defaultStylesheet].DIV.display to return the default style, as if my style sheets hadn't been added.

daveVk

3:12 am on May 20, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I was curious if anyone knows of a setComputedStyle


The computed style is the sum of all CSS rules plus direct style setting.

like 2 + 2 = 4;

I don't see how you can set 2 + 2 to 5;

You need to change the rules or direct setting to give result required.

vol7ron

4:12 pm on May 27, 2010 (gmt 0)

10+ Year Member



daveVk,

You are thinking too logically and not definitively. You could set 2+2=5 if you choose to override. 2+1 would still =3 and 2+3 would still =5, but you could override the 2+2=4 to 2+2=5 if you wanted.

Computed Style is the end result style, which is what the browser actually displays. So, it first takes the browser default styles, then takes external style pages, then takes internal style pages, then takes inline styles. Each next link in the chain overrides the previous link (there are other conditions that may affect the overriding though, such as when "important" designations are used).

The result of the chain is the computed style. My guess is that you can't override the computed style because of accessibility/security features, but it would be nice for what I'm trying to do.

mrhoo

4:28 pm on May 27, 2010 (gmt 0)

10+ Year Member



You can go through the document.styleSheets collection and edit any rule that matches the selector text or the cssText or both. It requires a separate syntax for IE8 (and lower) and every other browser, and it is a lot of work for the result.

Why not just change the className to one that does not set the default display to 'none'?

daveVk

12:52 am on May 28, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You can change one of the overriding steps in computing the style, but to me that is different from overriding the computed style.

I think obj.style.display='block' is treated as an override at some stage of the calculation

and obj.style.display='' is treated as "do nothing" at that stage