How do I move this javascript out of the head and into a .js to achieve valid markup?
November 13, 2006 5:44 PM   Subscribe

really basic, I think. You can't have <link /> tag inside a <script></script> using XHTML strict. I can't quite figure out how to write a function that takes the place of this basic little OS detection script <script type="text/javascript"> var cssFile = (navigator.userAgent.indexOf("Mac") != -1) ? "mac.css" : "everyonelse.css"; document.write("<link rel='stylesheet' type='text/css' href='../" + cssFile + "' />"); </script> Which I would put in the head of the document. How can I move it to a function in an external .js file and get the same result with valid xhtml 1.0 strict? It's not urgent, but it's driving me nuts because I'm really stupid about scripting but I know this sort of thing isn't supposed to be hard.
posted by Grod to Computers & Internet (17 answers total)
 
Best answer: Can you do it using the DOM? IE, replace the line:

document.write(....

with:

var newCSS = document.createElement('link');
newCSS.setAttribute('rel', 'stylesheet');
newCSS.setAttribute('type', 'text/css');
newCSS.setAttribute('href', "../"+cssFile);
document.getElementsByTagName('head')[0].appendChild(newCSS);
posted by null terminated at 5:52 PM on November 13, 2006


Also, avoid document.write whenever possible.
posted by null terminated at 5:53 PM on November 13, 2006


Couldn't you just change the offending line to:

document.write("< + link rel='stylesheet' 'text/css' href='../" + cssFile + "'/>");

?
posted by cerebus19 at 5:54 PM on November 13, 2006


Sigh. The formatting got screwed up there. It should be:

document.write("<" + "link rel='stylesheet' 'text/css' href='../" + cssFile + "'/>");
posted by cerebus19 at 5:55 PM on November 13, 2006


Response by poster: cerebus19. See what I mean about being stupid about scripting? I should've thought of that. It validates, but gives a warning:
Line 9 column 16: character "< is the first character of a delimiter but occurred as data./strong>

null terminated. Clever, it works great. Out of curiosity, why should I avoid document.write ?

posted by Grod at 6:11 PM on November 13, 2006


Response by poster: oops
posted by Grod at 6:11 PM on November 13, 2006


I believe document.write only works when used in the header. DOM manipulation is better style, as well, but I can't find the links to back that up.
posted by null terminated at 6:18 PM on November 13, 2006


DOM manipulation is better style, as well, but I can't find the links to back that up.

This is conventional wisdom among web developers, basically for the same reasons we use object-oriented programming and APIs - separating independent parts (e.g. JavaScript and HTML) makes it much easier to work with them independently.

On the other hand, here is an article from an authority on JavaScript explaining why document.write should only be used in one very specific situation, which is ironically the exact situation Grod seems to be dealing with: adding a specific stylesheet on for JavaScript-compliant browsers.
posted by scottreynen at 6:52 PM on November 13, 2006


"only for," that should be.
posted by scottreynen at 6:53 PM on November 13, 2006


I believe document.write only works when used in the header.
What do you mean by "works" here? document.write certainly "works" anywhere in a document, if "works" is taken to mean "performs its intended function."
posted by macrone at 6:57 PM on November 13, 2006


null, according to W3 document.write does not work in XHTML 1.1 strict. Basically, document.write() doesn't work on documents that are parsed by a browser using an XML parser as opposed to an HTML parser due to the fact that XML requires that an XML process abort on any well-formedness error*.
posted by RichardP at 6:59 PM on November 13, 2006


Oops, I meant to say it works only while the page is loading.
posted by null terminated at 7:02 PM on November 13, 2006


Here's a page about a document.write for XHTML. The two links in the first paragraph on that page go to pages with more discussion.

Line 9 column 16: character "< is the first character of a delimiter but occurred as data."

You should be able to use "\x3c" ... "/\x3e" to avoid the warning.
posted by blm at 8:40 PM on November 13, 2006


Response by poster: That site menu on quirksmode.org is amazing. Does anyone know of a tutorial explaining how to achieve the basic functionality? It's a switch menu that appears to store its state client side rather than server side, which is neat, and the killer, to my mind, is the option to have only one sub category available at a time. Lots of folding menu goodness.
posted by Grod at 8:41 PM on November 13, 2006


I think what null terminated is getting at is that any document.write statement that runs after the page is finished loading will create a new page and overwrite the content of the current page. Obviously, this is not good.
posted by littlelebowskiurbanachiever at 9:16 PM on November 13, 2006


Javascript is PCDATA
posted by weston at 10:13 PM on November 13, 2006


document.write should be avoided, but not to prevent the error you're seeing. It is undesirable for completely different reasons.

Try this:

<script>
// <![CDATA[

  
code here

// ]]>
</script>


The problem the validator is complaining about is having unescaped HTML characters (< and >) inside your <script> element. If you enclose everything in those bizarre <!CDATA[ ]]> delimiters than you don't need to escape your markup. The // comment markers are there to hide the CDATA block from browsers that don't understand it.

I'm an extreme stickler for proper validation and I use this on all of my pages to make my pages proper XHTML.
posted by Khalad at 7:03 AM on November 14, 2006


« Older Google Earth big images   |   Pow! Newer »
This thread is closed to new comments.