Create Dynamic Pop-ups in XHTML 1.0 Strict Pages

Tweet

I know what you’re thinking: "Pop-ups?" But, instead of looking at the negative way certain Websites and programs spring these nasties upon the unsuspecting populace, let’s think about the good they can do.

Now, several tutorials and scripts are available that allow you to create pop-ups upon clicking a link; others open the popup when the page loads.

But have you found any that allow you to create dynamic pop-ups — windows of different sizes, shapes, and configurations? No? I haven’t, either.

Pop-ups are easy to create: just paste javascript:window.open() in the HREF part of any anchor tag. The problem is that this approach will make your XHTML Web page invalid.

Pop-up Validation
<a href="somewhere.html" onclick="javascript:popupWin()">Some Link</a>

XHTML 1.0 document types do not allow you to place a JavaScript function in the anchor tag’s HREF attribute, but they do allow you to add functions to event handlers such as onclick and onmouseover. The theory of adding these event handlers is fine; the problem is that they look rather unsightly within the page’s XHTML code.

The solution is to put everything in the JavaScript itself — event handlers are essentially JavaScript, anyway!

One REL to Rule Them All

Let’s start by looking at what will cause our pop-up to come alive — the anchor’s markup:

<p><a href="http://www.somewhere.com/" rel="popup|600|400|0|1">SitePoint</a></p>

Notice anything out of the ordinary? That’s right — the REL attribute of the anchor tag looks different than normal.

That value:

  • tells the pop-up JavaScript whether the link should open in a pop-up window
  • dicatates the pop-up’s width and height
  • provides the values to toggle a new window’s attributes on or off
Snap, Crackle, Pop-Up!

Now, let’s look at a common example of the JavaScript function that will open a pop-up:

function popupWin(link,attribs) { 
    var popupWin = null;
    popupWin = window.open(link,'winPopup',attribs);  
}

This JavaScript function looks a lot like the countless other pop-up window scripts out there — but looks can be deceiving!

Instead of having the pop-up window’s destination and attributes specified in the window.open() function, in the function above, they are passed into the window.open() function by the link and attribs variables specified in the popupWin() function’s variables.

Pop Goes the JavaScript

Now, we need a function that will spider all the anchor tags, grab and use several values from those tags and, if they find what they’re looking for, turn those anchor tags into pop-up links. Here’s the code:

function popupWindows() { 
    if(!document.getElementsByTagName) {
         return;
    }
    var scrW = screen.availWidth;
    var scrH = screen.availHeight;
    var anchors = document.getElementsByTagName("a");
    for (var i = 0; i < anchors.length; i++) {
         var anchor = anchors[i];
         var linkDest = anchor.getAttribute("href");
         var relIndex = anchor.getAttribute("rel");
         var relSplit = relIndex.split("|");
         var windowAttributes = "";
         if(relSplit[0] == "popup") {
              if (relSplit[1] > scrW) {
                 pW = scrW - 10;
              }
              else {
                 pW = relSplit[1];
              }
              if (relSplit[2] > scrH) {
                 pH = scrH - 40;
              }
              else {
                 pH = relSplit[2];
              }
              scrX = (scrW - pW - 10) * .5;
              scrY = (scrH - pH - 30) * .5;
              var windowAttributes = "width=" + pW + ",height=" + pH + ",left=" + scrX + ",top=" + scrY + ",screenX=" + scrX + ",screenY=" + scrY;
              windowAttributes += ",location=" + relSplit[4] + ",resizable=" + relSplit[4] + ",scrollbars=" + relSplit[4];
              anchor.setAttribute("href", "javascript:popupWin('" + linkDest + "','" + windowAttributes + "')");
         }
    }
}
window.onload = popupWindows;
Pop-Up Breakdown

The first part of the JavaScript checks to see if the browser opening the document supports the getElementsByTagName method. If it does not, the script exits and the links will open in the same browser window.

if(!document.getElementsByTagName) {
         return;
    }

Next, we assign the variables:

  • scrW will hold the screen’s available width
  • scrH will hold the screen’s available height
  • anchors will hold an array of all the anchor tags on the page

var scrW = screen.availWidth;
    var scrH = screen.availHeight;
    var anchors = document.getElementsByTagName("a");

After these variables are assigned, we start to loop through the anchor tags. As we do so, we get two of the current anchor tag’s attribute values, HREF and REL. We then split up the REL attribute, taking the values between the vertical bars, and putting them into the relSplit array.

for (var i = 0; i < anchors.length; i++) {
         var anchor = anchors[i];
         var linkDest = anchor.getAttribute("href");
         var relIndex = anchor.getAttribute("rel");
         var relSplit = relIndex.split("|");

The next block of code basically checks to see if the first value of the relSplit array is "popup". If it is, the code checks the next two values of the relSplit array against the scrW and scrH variables from above. If either of the array values is larger than the variable to which it’s compared, the array value will shrink to fit the window.

The next variables, scrX and scrY, calculate the top-left corner position of the pop-up window, in order to center it on the screen.

if(relSplit[0] == "popup") {
              if (relSplit[1] > scrW) {
                 pW = scrW - 10;
              }
              else {
                 pW = relSplit[1];
              }
              if (relSplit[2] > scrH) {
                 pH = scrH - 40;
              }
              else {
                 pH = relSplit[2];
              }
              scrX = (scrW - pW - 10) * .5;
              scrY = (scrH - pH - 30) * .5;

In the next section of the code, the windowAttributes variable is assigned several of the values you would normally find in a pop-up window JavaScript: width, height, left, and top. Two other variables, which control the position of the pop-up window on the screen, also defined here: screenX and screenY.

var windowAttributes = "width=" + pW + ",height=" + pH + ",left=" + scrX + ",top=" + scrY + ",screenX=" + scrX + ",screenY=" + scrY;

You can set other attributes typically associated with JavaScript pop-ups: simply add them to the windowAttributes variable and use the other values in the relSplit array as the attribute’s values. Remember that you must add a '0' or '1', separated by a vertical bar, to the REL value of each link for each attribute you add to the windowAttributes variable.

For this particular script, I don’t want the location bar to display. I also want to be able to resize the window. To achieve these goals, I add the following to the windowAttributes variable:

windowAttributes += ",location=" + relSplit[3] + ",resizable=" + relSplit[4];

After the windowAttributes variable is set, we need to set the HREF value of the anchor tag equal to a normal JavaScript function. In our example, this is achieved with the following code:

anchor.setAttribute("href", "javascript:popupWin('" + linkDest + "','" + windowAttributes + "')");

Pop Into Action

Now, for this solution to work, we must have the JavaScript function load when the page loads. Adding an onload event handler to the BODY tag may suffice, but it will not support our goal of clean markup. Instead, at the end of the JavaScript, we’ll add window.onload = popupWindows. This makes the XHTML code look a lot cleaner, as everything is kept in the JavaScript.

To make your XHTML code even clearer, you can move these JavaScript functions to an external file and link it to every document that uses these pop-up links.

Now, having implemented this solution, you may find that any JavaScript you already have, which uses the window.onload method, no longer works. Don’t despair — just create a new function named initialize and place into it the names of the two functions that need to load when the page loads. Use the window.onload method to call this function.

For example, let’s say I have another script named hideDivs that hides certain divs until the user clicks a link. In this case, the JavaScript function would look like this:

function initialize() { 
    popupWindows();
    hideDivs();
}
window.onload = initialize;

Yet another way to add this script to your page, and have it execute when the page loads, is to use Simon Willison’s closure technique.

Browser Caveat

One problem with this script is the fact that, like Web standards, each browser has its own way to implement this script.

For example, Internet Explorer 5.x and Opera for both Windows and Mac skip over anchor tags for which a REL attribute is not specified, and continue on to the next anchor tag. Mozilla and Netscape browsers, on the other hand, seem to want to "break" the script at any anchor tag for which a REL attribute is not specified. They cease execution of the script and don’t implement it at all.

Remember, if you use this script, a REL attribute must be specified for each anchor tag in your page.

Common Applications

There are several uses for a script such as this.

One example application might involve online photo gallery, where clicking on a picture thumbnail opens the full-sized picture in a pop-up window. Also, if the pictures are different sizes, the size of the pop-up could be specified for each photo.

Further Reading

To learn more about pop-ups and all the good things you can do with them, check out these links:

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

No Reader comments