[thelist] Javascript off CSS on hide elements in page

Andrew Clover and-evolt at doxdesk.com
Mon Mar 28 06:14:49 CST 2005


Tony Crockford <boldfish at gmail.com> wrote:

> what I wanted to do was turn off (display:none) the elements that
> needed javascript when they are replaced by their noscript
> equivalents.

It's probably best to set the 'display: none' rule (or, better, just 
removeChild) on the element nodes themselves, in the JavaScript that 
replaces them with something. That way, you know that they will only be 
hidden if the replacement is completely successful.

(If there is a JS error, or scripts have been partially blocked or 
something, the original elements will still be visible. This is a Good 
Thing because JavaScript is, essentially, inherently unreliable.)

What you are trying to do is a very nasty hack, but is achievable with 
valid code, and can be useful in the direst of emergencies!

To make both the original document and the version altered by the 
document.write() valid HTML, you only need to be slightly more caereful 
with the comments.

In legacy SGML-based HTML, a '--' string inside a comment has the effect 
of swapping between being a comment and begin some SGML junk that isn't 
a comment but will typically be ignored. To end a comment properly, you 
have to ensure there's an even number of '--' tokens between the <!-- 
and the -->.

So, firstly, you shouldn't include the string '--' in the <script> 
sections. Instead, you could write something like:

   document.write('<!-\-');

This will also stop the validator complaining in XHTML mode. In XML, the 
string '--' is simply not allowed in comments at all (it was felt that 
this was simpler than allowing it but with possibly-unexpected 
consequences, as HTML does).

Secondly, it means that if the first <script> block does write a '<!--', 
the remaining post-script markup as seen by the parser is:

   <!-- [1]
   <link rel="stylesheet" ... />
   <script type="text/javascript">
   <!-- [2]
     document.write('-- [3]' + '>');
   //-->
   </script>

The parser is in a comment at [1], out of a comment again at [2] 
(followed by some SGML garbage) and in a comment again at [3], just in 
time for a proper end-of-comment '-->' tag. Unfortunately there's then 
an unmatched </script> tag. Browsers will generally ignore this... not 
if they are in full XML-parser mode but we'll come to that in a minute.

So if you expected the second <script> block to be executed, you'd be 
mistaken. The processing of comments and script blocks occurs in line, 
so by outputting the '<!--' string, the first script block stops the 
second script block from being a script block at all. All you really 
need to do is end the comment; a slightly quicker way of doing so would be:

   <script type="text/javascript"><!--
     document.write('<!-\- -\- ');
   //--><script>
     ...stuff to be hidden...
   <!-- -->

Now if you're writing XHTML, you'd generally want the page also to work 
with browsers' real-XML-parsing modes, as used when the pages are served 
under the MIME type application/xhtml+xml. So you wouldn't want to wrap 
the script block in <!-- -->, because in XML this would *really* make it 
a comment, and hence no script would execute.

However... typically in real-XML-parsing modes, document.write() does 
not work, full stop. And it doesn't work precisely to stop you doing 
stuff like this. So I'd forget trying this trick with XHTML.

-- 
Andrew Clover
mailto:and at doxdesk.com
http://www.doxdesk.com/

-- 
Andrew Clover
mailto:and at doxdesk.com
http://www.doxdesk.com/


More information about the thelist mailing list