| View previous topic :: View next topic |
| Author |
Message |
Nick Forum Moderator

Joined: 18 Jun 2002 Posts: 3635
|
Posted: Sun Apr 02, 2006 6:34 pm Post subject: Unobtrusive JavaScript Popup Windows |
|
|
Unobtrusive JavaScript Popup Windows
Learn how to use JavaScript events and triggers without using inline scripting, therefore allowing visitors to use your site even with JavaScript disabled.
Introduction
In this new regenerated world of web development there is a desire to use advanced features on sites, yet maintain usability, accessibility and backwards compatability. Many "advanced" features, such as image galleries, form validation and pop-up windows require JavaScript to function properly. This means that users with JavaScript disabled (they do exist!) are unable to use your site. And when these advanced features make up critical paths for your visitors, you're destroying usability and accessibility.
A quick and dirty JavaScript example
Let's look at the JavaScript we so often use to create pop-up windows. Love 'em or hate 'em, they do have their place in our arsenal if used meaningfully to enhance the browsing experience. The following example is how a developer might code a pop-up window event.
| Code: | | <a href="#" onclick="javascript:window.open('page.html','popup','width=400,height=200');">View new page</a> |
What's wrong with that?
The only good thing about the example above is that it works. However, there are a number of problems with this code:
a) Maintainability of inline JavaScript
The raw JavaScript code is inserted "inline" to an element in the page HTML. If you want to update the widths of your pop-ups, or change the way your window opens, you are going to have to edit this code in every page of your site. Moving the JavaScript code to an external .js file will improve maintainability.
b) If JavaScript is disabled...
The "onclick" event will not be triggered, and the link reference has been set effectively to nowhere ("#"). To a browser with JavaScript disabled (whether it be a visitor or a search engine robot) this link is now useless. It goes nowhere.
Improving the markup
Problems are solved most easily when the (X)HTML markup is simple and clean. Keep It Simple, Stupid. Here is a suggested simplified link. Notice I have added a class attribute to the anchor element. You'll see why later.
| Code: | | <a href="page.html" class="popup">View new page</a> |
Using JavaScript to add the pop-up event
The following JavaScript function will create our popup actions once the page has been loaded. The script looks through our document (Document Object Model) for all link (anchor) elements. For each link, the script checks to see whether this link is to be opened as a pop-up (i.e. whether it has been assigned a class of "popup"). If so, an onclick event is added to the link element which triggers a new function containing our original pop-up code (from the inline example at the top of the article).
| Code: | window.onload = function() {
// check to see that the browser supports the getElementsByTagName method
// if not, exit the loop
if (!document.getElementsByTagName) {
return false;
}
// create an array of objects of each link in the document
var popuplinks = document.getElementsByTagName("a");
// loop through each of these links (anchor tags)
for (var i=0; i < popuplinks.length; i++) {
// if the link has a class of "popup"...
if (popuplinks[i].getAttribute("class") == "popup") {
// add an onclick event on the fly to pass the href attribute
// of the link to our second function, openPopUp
popuplinks[i].onclick = function() {
openPopUp(this.getAttribute("href"));
return false;
}
}
}
}
function openPopUp(linkURL) {
window.open(linkURL,'popup','width=400,height=200')
} |
Ideally this code should be saved to a separate file to your HTML document, say popup.js. Then import the JavaScript in your document link this:
| Code: | | <script type="text/javascript" src="popup.js"></script> |
Conclusion
Using the DOM (Document Object Model) we have successfully read the page for anchor tags. If the link needs to be opened in a popup, the we have added an event to the link. If JavaScript is disabled, then the link tag will act as a normal hyperlink, allowing our visitors to continue browsing the new page in the main browser window. This implements the concept of 'progressive enhancement' using unobtrusive JavaScript techniques - functionality that adds value to pages, but isn't a requirement.
Further reading
This article was inspired by examples in Jeremy Keith's fantastic DOM Scripting book. The book offers a brief history and introduction of JavaScript and begins with simple examples to teach best practices and unobtrusive scripting. I would recommend it to anyone. |
|
| Back to top |
|
 |
Nick Forum Moderator

Joined: 18 Jun 2002 Posts: 3635
|
Posted: Mon Apr 03, 2006 4:21 pm Post subject: |
|
|
Further applications
In XHTML you are no longer supposed to use the "target" attribute for links. For example, you may not use _blank to open a new window:
| Code: | | <a href="page.html" target="_blank">Click</a> |
As such, you can mark up your external links with a new class name use the unobtrusive JavaScript method in the article. Let's say you give all outbound external links a class of "external-link":
| Code: | | <a href="..." class="external-link">Click</a> |
You should then add a second if() statement within the for() loop in the main function in the article.
| Code: | if (popuplinks[i].getAttribute("class") == "external-link") {
// add an onclick event on the fly to open a new browser window
popuplinks[i].onclick = function() {
window.open(this.getAttribute("href"));
return false;
}
} |
Any links given a class of "external-link" will open in a new browser window. _________________ Nick Dunn
Nick Dunn
Last edited by Nick on Mon Apr 03, 2006 9:19 pm; edited 1 time in total |
|
| Back to top |
|
 |
Mark Voss Divine Being

Joined: 19 Jun 2002 Posts: 4946 Location: Cardiff, UK
|
Posted: Mon Apr 03, 2006 7:19 pm Post subject: |
|
|
I use a very similar method to this but found that using:
| Code: | | .getAttribute("class") == | didn't work in Internet Explorer.
A quick Google revealed that in IE you can use either
| Code: | | .className == or .getAttribute('className') == |
and in other browsers you can use either
| Code: | | .className == or .getAttribute('class') == |
So, replacing with:
works in all browsers including IE. _________________ Mark Voss
http://www.markvoss.net |
|
| Back to top |
|
 |
Nick Forum Moderator

Joined: 18 Jun 2002 Posts: 3635
|
Posted: Mon Apr 03, 2006 8:27 pm Post subject: |
|
|
Bleugh, there I was assuming that current generation browsers were implementing the DOM, and more importantly the HTML-DOM correctly. Sadly not. Yep, Mark is right, the following ammendments should be made for complete browser consistency:
| Code: | | popuplinks[i].getAttribute("class") == "popup" |
Changes to:
| Code: | | popuplinks[i].className == "popup" |
Note: "class" is a reserved word in JavaScript, hence we use "className" instead.
One day we'll get simple things like the DOM implemented consistently. _________________ Nick Dunn
Nick Dunn |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB 2.0.11 © 2001, 2002 phpBB Group
|