Dear CSS/Javascript/DOM/Safari Wizards,
WHAT I AM TRYING TO DO:
It seems to be difficult to establish a cross-browser signaling mechanism
between Javascript and what style sheet has been applied as the browser
selects a media type.
I am attempting to dynamically add a flyout menu via the DOM after the
window.onload event has been triggered. However, I only wish that to be
added for certain media types, namely the screen, rather than handheld
users (who won't have enough space for it) and users who do not have CSS
enabled (browsers for the blind, search engines, etc.) in the name of
accessibility. While display: none would work for some handheld users (in
theory), it is obviously not going to work for users who have no CSS, but
still execute Javascript.
Naturally, I'd like to find out, via Javascript, what stylesheet has been
selected in response to the given media type.
METHODS I HAVE TRIED:
Access current styles:
Thus far, I have been applying the stylesheet, then using getComputedStyle
and currentStyle (depending on Firefox vs. Internet Explorer) to see what
styles have been applied to a small, "canary in the coalmine" element. A
2px left padding indicates a screen user, a 1px left padding indicates a
handheld user, and no padding indicates someone who does not have CSS
enabled at all.
This approach has not worked in Safari. It appears to be failing when I
try to get the current style, giving me an "undefined" return.I don't have
a Mac that I can easily test on. BrowsrCamp is nice, but it's hard to
debug from screenshots, and I have no way to click on elements to
eliminate the possibility that window.onload is firing before the external
stylesheets are quite done parsing.
The function looks like:
function getStyle(el,IEstyleProp, MozStyleProp) {
var x = document.getElementById(el);
if (x.currentStyle) {
var y = x.currentStyle[IEstyleProp];
} else if (window.getComputedStyle) {
var y =
document.defaultView.getComputedStyle(x,null).getPropertyValue(MozStyleProp);
}
return y;
}
The function is called as such:
getStyle('canary','paddingLeft','padding-left');
Document.styleSheets:
Simply looping through the document.styleSheets collection hasn't helped -
it tells me that, for all of my stylesheets, the .disabled value is
"false." This happens on both FireFox and Internet Explorer, so I imagine
Safari would give similar results. Only deliberately setting the value to
"true" enables me to later read out a "true" value, which is of no help.
A List Apart:
Alternately, are there DOM-compliant methods so I can simply see what
stylesheet has been selected out of a list like the document.styleSheets
collection, after a windows.onload triggers? There's a method from A List
Apart (http://alistapart.com/stories/alternate/) that looked promising,
but it is based on setting style sheets, not reading if a style sheet has
been set by a media type. Setting the "rel" attribute of a link to a
stylesheet to "alternate stylesheet" causes Firefox to simply fail to load
the sheet.
CSS Generated Content:
I have also attempted to use :before and :after pseudoclasses to generate
content. The generated content is indeed added to the rendering of the
page, yet it does not seem to be added to the DOM. It does not show up in
FireFox's DOM Inspector. Using border styles, it appears that the
generated content is added to the text node, but direct access of that
text via nodeValue only shows the original content! Somehow, the rendered
content does not add itself to the DOM. This occurs even if I wait a few
seconds and trigger the detection code with an onclick on a form button.
Naturally, this method leaves out Internet Explorer 6.0, which does not
support generated content, but I could combine it with a different
technique to cover all of my bases - if only it worked!
CSS: #target p:before {
content: 'screen ';
}
HTML: <div id="target"><p id="interiorp">with paragraph node
inside</p></div>
Javascript: function detector() {
var target = document.getElementById('interiorp');
var newpara = document.createElement('p');
newpara.appendChild(document.createTextNode('Number of child nodes: ' +
target.childNodes.length ));
newpara.appendChild(document.createElement('br'));
var i, a;
a = target.childNodes.length - 1;
for (i=0; i <= a; i++) {
newpara.appendChild(document.createTextNode('Loop value: ' +
i));
newpara.appendChild(document.createElement('br'));
newpara.appendChild(document.createTextNode('nodeType: ' +
target.childNodes[i].nodeType));
newpara.appendChild(document.createElement('br'));
newpara.appendChild(document.createTextNode('nodeName: ' +
target.childNodes[i].nodeName));
newpara.appendChild(document.createElement('br'));
newpara.appendChild(document.createTextNode('nodeValue: ' +
target.childNodes[i].nodeValue));
newpara.appendChild(document.createElement('br'));
}
CSS Generated Content, Variation 2:
Opera supports Javascript calls in generated content, like so:
element:after { content: url("javascript:somefunction();"); }
Unfortunately, Safari does not.
ADDITIONAL QUESTIONS:
I have also been unable to find statistics on the adoption of various
versions of Safari. If my solution won't work with Safari 1.3, I'd like
to know what percentage of Safari users I'll be inconveniencing.
Obviously, I'm also looking to please users of IE 5.5 and above,
Mozilla/Firefox/Netscape, and Opera, and so far I have been in luck. Only
Safari has stymied me with my attempts to use current styles as a
detection method.
I apologize for the length of this post. Thank you for your time.
Regards,
Ian
______________________________________________________________________
css-discuss [EMAIL PROTECTED]
http://www.css-discuss.org/mailman/listinfo/css-d
IE7b2 testing hub -- http://css-discuss.incutio.com/?page=IE7
List wiki/FAQ -- http://css-discuss.incutio.com/
Supported by evolt.org -- http://www.evolt.org/help_support_evolt/