Let's Go!
Navigating the tutorial
Please use the navigation section on the left side of each web document to view the tutorial topics, and the TOP button at the end of each page section to return to the top of the page.
This Fast Track tutorial demonstrates how to replace the <noscript> markup element with an unobtrusive DOM/JavaScript function named noscript.js.
Peter-Paul Koch in his book "ppk on JavaScript", points out that the <noscript></noscript> element has a limitation. Modern user agents with JavaScript enabled will hide content contained
within <noscript></noscript>, and reveal it when JavaScript is disabled. User agents that do not support JavaScript will display the content within it. User agents with partial/antiquated JavaScript capabilities however interpret
the element correctly and do not show the content, but when JavaScript is disabled also do not show the content - it never gets seen. This has an impact on the accessibility of the content.
If your writing is targeted at modern, standards-based, compliant, and fully capable JavaScript user agents, employing the <noscript> element is no problem. If the user agents among your audience are unpredictable, however, replacing the <noscript>
element with another mechanism becomes significant. This article looks at one such solution.
The solution
So, how can the behavior intended by the <noscript> markup element be enabled in these antiquated/partially-capable JavaScript user agents?
- Important Note: if the ability to hide the alternative content with JavaScript does not exist, the browser/user agent will be able to render the content ensuring accessibility and graceful degration.
The workflow for my solution is as follows:
- Insert an unobtrusive JavaScript "hook" via an
idattribute value in the parent container's opening tag. - Associate the "hook" with an external JavaScript function, which sets up a parent-to-child relationship between the container and its content.
- When Javascript is enabled, the external function keeps the alternative content hidden.
- If the user agent cannot interpret the JavaScript expressions, the alternative content in the markup is revealed.
- When Javascript is disabled the function no longer works, and the alternative content in the markup is revealed.
- This ensures graceful degradation of the script, and access to the alternative, hidden content.
Building the Markup
In this section you'll build the markup portion of the example.
- In the
<head></head>element of the web page, insert a<script></script>element containing the path to the externalnoscript.jsJavaScript file: - Create a
<div></div>within the<body></body>element to contain the hidden content. - Give the opening tag of the
<div>anidattribute with a value of"noscript", that is,<div id="noscript">- This sets the unobtrusive hook to the external JavaScript function
noscript().
- This sets the unobtrusive hook to the external JavaScript function
- Place all elements and content to be hidden while JavaScript is enabled within the
<div id="noscript"></div>container.
The following web page markup sample illustrates this:
-
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-
"http://www.w3.org/TR/html4/strict.dtd">
-
<html lang="en">
-
<head>
-
<title>noscript_example</title>
-
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
-
<script src="scripts/noscript.js" type="text/javascript"></script> -
</head>
-
<body>
-
<div id="noscript"> -
<p> -
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. -
</p> -
<ul> -
<li><a href="#">Hyperlink A</a></li> -
<li><a href="#">Hyperlink B</a></li> -
</ul> -
</div> -
</body>
-
</html>
Building the unobtrusive DOM/JavaScript
In this section I'll take you through building up the two main sections of the JavaScript.
Writing the if() portion of the function
- Between the
ifparentheses, place thedocument.removeChildexpression - this tests to see if it is supported by the user agent.- If it is supported the function will continue, and the
divcontent will remain hidden. - If it is not supported the function progresses to the
else if()statement and tests it.
- If it is supported the function will continue, and the
- Declare the container
divelement and identify itsidvalue as the external, unobtrusive "hook" to the markup. - Instruct the parent
divto remove all child content within it.
Writing the else if() portion of the function
- Between the
else ifparentheses, place thedocument.getElementByIdexpression to test if it is supported by the user agent.- If it is supported the function will continue, and the
divcontent will remain hidden. - If it is not supported the function will end, and the
divcontent will be revealed, establishing graceful degradation of the script.
- If it is supported the function will continue, and the
- Return the element
idwhere the style will be applied. - Set its
style.displayto "none" to control the presentation aspect of the child content.
The following JavaScript functions are contained in the noscript.js file, which is kept external to the web page in the scripts folder, and linked to the web page as described in the "Building the Markup"
section.
-
/* noscript.js */
-
function addLoadEvent(func) { -
var oldonload = window.onload;
-
if (typeof window.onload !== "function") { -
window.onload = func;
-
} else { -
window.onload = function () { -
if (oldonload) { -
oldonload();
-
}
-
func();
-
};
-
}
-
}
-
var noscript = addLoadEvent(noscript); -
addLoadEvent(function () { -
/* more code to run on page load */
-
});
-
-
function noscript() { -
if (document.removeChild) -
{ -
var div = document.getElementById("noscript"); -
div.parentNode.removeChild(div);
-
}
-
else if (document.getElementById) -
{ -
document.getElementById("noscript").style.display = "none"; -
}
-
}
Summary
This article demonstrates a solution that replaces the <noscript></noscript> markup element with an external, unobtrusive JavaScript function. The noscript() function solves the problem that partially-capable/antiquated
JavaScript user agents have with not revealing alternative content if JavaScript is disabled. Employing this function, they will reveal the content as intended. This ensures graceful degradation of the script, and full accessibility to the alternative
content.