15

Is there a HTML tag that does the opposite of <noscript>? That is, displays some content only if JavaScript is enabled? For example:

<ifscript>
<h1> Click on the big fancy Javascript widget below</h1>    
<ifscript>

Of course <ifscript> doesn't actually exist. I know I could achieve the same result by adding <h1> to the DOM using JavaScript, but if I'd prefer to do this with (X)HTML if possible.

Thanks, Donal

Dónal
  • 185,044
  • 174
  • 569
  • 824

5 Answers5

35

There the <script> is for. Just initially hide the particular piece using CSS and use JavaScript to display it. Here's a basic kickoff example:

<!doctype html>
<html lang="en">
    <head>
        <title>SO question 2297643</title>
        <script>
            window.onload = function() {
                document.getElementById("foo").style.display = 'block';
            };
        </script>
        <style>
            #foo { display: none; }
        </style>
    </head>
    <body>
        <noscript><p>JavaScript is disabled</noscript>
        <div id="foo"><p>JavaScript is enabled</div>
    </body>
</html>

...or, with little help of jQuery ready() which is a tad sooner with displaying the content:

<!doctype html>
<html lang="en">
    <head>
        <title>SO question 2297643 with jQuery</title>
        <script src="http://code.jquery.com/jquery-latest.min.js"></script>
        <script>
            $(document).ready(function() {
                $('#foo').show();
            });
        </script>
        <style>
            #foo { display: none; }
        </style>
    </head>
    <body>
        <noscript><p>JavaScript is disabled</noscript>
        <div id="foo"><p>JavaScript is enabled</div>
    </body>
</html>

To improve user experience, consider placing the <script> call directly after the particular HTML element which needs to be toggled, so that there's no "flash of content" or "element shuffle". Andrew Moore has given a good example in this topic.

Alternatively, you can do it (hacky) the other way round with <style> in <noscript>. This is syntactically invalid, but allowed by all browsers from IE6 and up, including the W3C-strict Opera:

<!doctype html>
<html lang="en">
    <head>
        <title>SO question 2297643 with CSS in noscript</title>
    </head>
    <body>
        <noscript>
             <style>#foo { display: none; }</style>
             <p>JavaScript is disabled
        </noscript>
        <div id="foo"><p>JavaScript is enabled</div>
    </body>
</html>
Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • 1
    Showing the element in the `onload` handler could cause the page to reflow, moving elements. The element would also not appear until all images on the page had finished loading, not a good thing if you're fetching a large image from a slow server :-) jQuery's `ready` callback wouldn't have this problem, as it works as soon as the document is parsed. – Andy E Feb 19 '10 at 16:19
  • Yes, the jQuery way or the CSS-in-noscript is more preferred. – BalusC Feb 19 '10 at 16:22
  • Using the jQuery approach doesn't truly indicate that javascript is disabled in the browser, it could mean that jQuery isn't loaded (blocked perhaps) or the CDN was down/unavailable, meanwhile your YouTube videos and Facebook widgets continue to work fine. – Wesley Murch Oct 29 '11 at 07:59
19

I usually do the following in my HTML pages:

<html>
  <head>
    <!-- head tags here -->
  </head>
  <body class="js-off">
    <script type="text/javascript">
      // Polyglot! This is valid MooTools and jQuery!
      $(document.body).addClass('js-on').removeClass('js-off');
    </script>

    <!-- Document markup here -->
  </body>
</html>

Using this technique has the following advantages:

  • You can target both browsers with JavaScript enabled and those without directly in your CSS file.

  • It's valid XHTML (<style> tags in <noscript> is invalid, <noscript> tags in <head> is invalid).

  • The style changes first thing even before the rest of the page is rendered. It fires before domReady therefore no styling flashes.

That way, when you have widgets with different style depending if JS is enabled or not, you can define your style at the same place in the CSS file.

<style type="text/css">
  #jsWarning {
    color: red;
  }

  #jsConfirm {
    color: green;
  }

  body.js-on #jsWarning,
  body.js-off #jsConfirm {
    display: none;
  }
</style>

<div id="jsWarning">This page requires JavaScript to work properly.</div>
<div id="jsConfirm">Congratulations, JavaScript is enabled!</div>
Andrew Moore
  • 93,497
  • 30
  • 163
  • 175
  • 2
    +1 for this interesting solution. – OregonGhost Feb 19 '10 at 17:11
  • 3
    +1 This is a nice "real-world" solution. – BalusC Feb 19 '10 at 17:50
  • Wait, both js-on and js-off classes are set to display:none ... ? And also, if you are manipulating the BODY tag to be invisible - you will not see your noscript message either. – rlb.usa Mar 11 '10 at 20:54
  • 2
    @rlb.usb: Please read the CSS rule carefully. `body.js-on #jsWarning` doesn't mean that I'm modifying body. It means that I'm modifing a tag with `id="jsWarning"` that is within a ``. – Andrew Moore Mar 12 '10 at 00:20
  • 1
    +1 Great solution @Andrew Moore - I've been looking, and this is by far the most elegant and simple way I've seen. – Dan Lugg Jul 28 '11 at 01:23
8

How about

<script>
document.write("<h1>Click on the big fancy Javascript widget below</h1>");
</script>

? Convert to use DOM tree if you like.

kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005
3

This will work:

<script type="text/javascript">
 if (document != undefined)
 {
    document.write("Woohoo, JavaScript is enabled!");
 }
</script>
<noscript>
Sorry mate, we use JavaScript here.
<noscript>
Piotr Rochala
  • 7,748
  • 2
  • 33
  • 54
  • 1
    It's however ugly and errorprone if you want to do this for a "complete" HTML page. – BalusC Feb 19 '10 at 16:12
  • 2
    @BalusC: Why would you do it for a "complete" html page? You don't add the ` – Andy E Feb 19 '10 at 16:15
  • @Andy E: Often, noscript is used in combination with a *complete hide* of the remnant of the HTML page, because it's impossible to use the particular page without JS. – BalusC Feb 19 '10 at 16:17
  • @BalusC: And often it's not, I'm not sure I see your point. I'd say more often than not it's just used to alert the user to a lack of advanced functionality within the site. Switch off your javascript and reload SO for an example. – Andy E Feb 19 '10 at 16:22
  • 1
    @Andy E: Then there would be no reason to ask for the opposite of noscript. Let's stay in the context of this topic ;) – BalusC Feb 19 '10 at 16:23
1

There is an interesting discussion of these issues at Alex Papadimoulis's Blog. It includes an asp.net ScriptOnly control which acts like the ifscript control you asked about.

Brian
  • 25,523
  • 18
  • 82
  • 173