Aug 28

The Opposite of the NOSCRIPT Element (YesScript? / ScriptOnly?)

In search of the opposite of NOSCRIPT...

The HTML NOSCRIPT element is very simple and straightforward:

18.3.1 The NOSCRIPT element

The NOSCRIPT element allows authors to provide alternate content when a script is not executed. The content of a NOSCRIPT element should only be rendered by a script-aware user agent in the following cases:

  • The user agent is configured not to evaluate scripts.
  • The user agent doesn't support a scripting language invoked by a SCRIPT element earlier in the document.

User agents that do not support client-side scripts must render this element's contents.

There is no HTML element that will do the opposite of this. The SCRIPT element will execute its contents, not render it. Of course, we could use document.write() to insert content in the page only when JavaScript is enabled:

<script type="text/javascript">
//<![CDATA[
    document.write("<p>Hello World! JavaScript is enabled.</p>");
//]]>
</script>
<noscript>
    <p>Hello World! JavaScript is disabled.</p>
</noscript>

That will work just fine in some cases, but it isn't valid XHTML and it breaks when serving the page with the XHTML/XML MIME type. Plus, it is just nasty and ugly looking... :)

Does document.write work in XHTML?

No. Because of the way XML is defined, it is not possible to do tricks like this, where markup is generated by scripting while the parser is still parsing the markup.

You can still achieve the same effects, but you have to do it by using the DOM to add and delete elements.

As stated above, there are DOM method alternatives that can be used to implement this functionality. But again, this creates a mix of HTML and JavaScript that is unmaintainable (especially if the content is data driven and/or being managed by business users).

A cleaner way would be to include the content in the page as you normally would, have it hidden by CSS and then show it via JavaScript. If there is no JavaScript, then it will not be rendered.

HTML:

<p class="YesScript">
    Hello World! JavaScript is enabled.
</p>

CSS:

.YesScript { display:none; }

JavaScript (jQuery syntax):

$(document).ready(function(){
    $('.YesScript').show();
});

This does the trick, but in some cases (especially IE) the page will render before the JavaScript, causing the page to "flicker" when the content all of a sudden appears. This is very undesireable, as it can cause epileptic seizures... Uhm, on a more serious note, it is just very annoying to the eye. So, what if we could apply CSS rules based on the availability of JavaScript? Here is how to do it with one line of JavaScript in the HEAD of the HTML document:

HTML:

<html>
    <head>
        <title>...</title>
        <script type="text/javascript">
        //<![CDATA[
            document.getElementsByTagName('html')[0].className='jsOn';
        //]]>
        </script>
    </head>
    <body>
        <p class="YesScript">
            Hello World! JavaScript is enabled.
        </p>
    </body>
</html>

CSS:

.YesScript { display:none; }
.jsOn .YesScript { display:block; }

This is the best solution I have found. You add a class to the HTML element via JavaScript in the HEAD of the document and then use that to target your CSS rules and styling. This can also be used to hide elements that you need to have in the DOM but don't want them to initially render (elements declared in the NOSCRIPT tag will not be available in the DOM if JavaScript is enabled). A use case for this would be for Tab content (you want all the panels hidden except the active one).

Cheers!

Powered by my hackings on Django-Mingus a Django project, PostgreSQL, memcached, nginx, Apache + mod_wsgi, Ubuntu, Rackspace Cloud,...

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

html5 | top