Accessible Pop-up Links

Sometimes we have to use pop-ups — so we might as well do them right. This article will show you how to make them more accessible and reliable while simplifying their implementation.

Article Continues Below

For the purposes of this article, pop-up links are links that open in a new window, and that rely on JavaScript to do so. Ordinarily, all you need for a link to open on a new window is to set its “target” attribute to “_blank”. With pop-up links, JavaScript is used either because special window properties must be set, or because the DOCTYPE in place does not allow the “target” attribute.

Links 101#section2

The concepts here are very simple, but let’s get some terminology clear before we continue:

We’ll be using here the HTML “a” element and dealing with its “href” and “target” attributes. We’ll also use the “window.open” JavaScript method and refer to its arguments “url,” “name,” and “features”. Below is a table describing these items and their equivalence between HTML and JavaScript.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Concept a attribute window.open parameter Description
Link destination href url The URI of a resource to be loaded
Target window target name An identifier of the window where the resource should load
Features N/A features Chrome/UI properties of the target window

The bad#section3

First, let’s put an end to the problem with most JavaScript pop-up links: their HTML. Here’s a representative sample:

<a href="JavaScript:
  raw_popup('http://example.com');
  void(0)">pop me up

This piece of HTML is the root of all that’s unholy in the pop-up world. It sports two serious usability issues that would otherwise be easily avoidable. The first one should be clear: users without JavaScript are unable to follow the link.

The reason why the link won’t load for these users is simple, and stupid: the link destination is set to an action (a JavaScript function), rather than to its actual destination. Depressingly, the purpose of this function is to load the actual link destination.

The ugly#section4

The second issue is not so obvious, but comes with its own interesting irony: the link will fail for the very people who concur with the designer’s decision: users who already planned to open the link in a new window.

When I intentionally open a link in a new tab or window, here’s a simplified description of what the browser does: it grabs the value specified in the link’s “href” attribute and it sets it as the location for the new tab or window.

If JavaScript is disabled, we reach the same issue described before. If JavaScript is enabled, however, the browser will call the pop-up function within the scope of the new window’s location bar — and it’ll fail, because the function only exists within the scope of the original page. In other words, when you open a new window and it tries to run that JavaScript function, it will fail because the new window has never heard of that JavaScript function.

A place for everything…#section5

You’ll notice that both problems stem from the same mistake: they specify something that’s not the link’s destination as the link’s destination.

A better approach would be to specify the link’s destination correctly in the “href” attribute, and use an event handler (which is where you place JavaScript code) to open the new window and set its special properties.

Here’s a simple approach:

<a href="http://example.com">pop me up

We can avoid redundancy by passing the element to the function and having it read the URL from the “href” attribute:

<a href="http://example.com">pop me up

The former example is still useful when you want to provide a separate URL for users without JavaScript. Keep in mind that the URL that will open for users who manually launch the link in a new window will be the one specified in the “href” attribute, not the one passed via script. (You can always use a JavaScript redirect in that page.)

If you were hoping to see some kickass JavaScript, hold on. For now, we’re not interested in the actual JavaScript implementation, we’re just trying to define the best HTML code. Either example above would already solve the accessibility problems because the “href” attribute contains the actual link destination. It’s good enough, but we can make it better.

Do it with HTML#section6

A guideline I use while coding is that I should only script what HTML cannot handle. If it can be done in HTML, then it should be. JavaScript should come as a complement.

So can HTML follow a link? Yes. Can HTML make this link load in a new window? Yes. (With transitional DOCTYPEs at least.) Can HTML determine the chrome features of this window? No. This is where JavaScript should come in.

So here’s our improved HTML code:

<a href="http://example.com"   target="_blank">pop me up

By adding the “target” attribute we make sure that the link will open in a new window even if the user doesn’t have JavaScript enabled, although the window’s features won’t be set.

A note for accessibility aficionados#section7

Our events will not trigger exclusively for mouse users despite the fact that we’re only capturing “onclick”. “Onclick” is triggered by all forms of activation (e.g. pressing enter) on all popular browsers. (It works pretty much the same way as Mozilla’s XUL’s oncommand.)

Implementation#section8

Now that our HTML is tidy, let’s get our hands dirty with the JavaScript implementation. I’ll spare you the simple one-liner (that would be a dull window.open wrapper) and provide you with some full-featured pop-up handling code:

var _POPUP_FEATURES = '
  location=0,
  statusbar=0,
  menubar=0,
  width=400,
  height=300
';function raw_popup(url, target, features) {
  if (isUndefined(features)) {
    features = _POPUP_FEATURES;
  }
  if (isUndefined(target)) {
    target = '_blank';
  }
  var theWindow =
    window.open(url, target, features);
  theWindow.focus();
  return theWindow;
}function link_popup(src, features) {
  return
    raw_popup(src.getAttribute('href'),
    src.getAttribute('target') || '_blank',
    features);
}

There’s a lot of stuff here, so let’s take a closer look:

raw_popup is a fancy “window.open” wrapper with a couple of things to make our life easier:

  • Better defaults: if no target window is provided, it’ll default to _blank. If no features are specified, it’ll default to the global constant _POPUP_FEATURES.
  • Focus: if the target window is already open but in the background, it’s brought to the front. The target window may be open in the background if we are using named windows (by specifying a target other than _blank), and sending more than one link to the same target. It’s good usability to focus the window because otherwise the user would get no apparent feedback for clicking the link.

link_popup was created specifically to open new windows from links. It grabs the URL from the anchor tag’s href attribute and optionally grabs the target from the target attribute. If the latter is not provided, it’ll default to _blank. This makes the function compatible with strict documents while allowing usage of named target windows. You should always specify a target in the HTML code when using a transitional DOCTYPE, to aid users without JavaScript. It’s good practice to write functions that return something, and nothing is more natural than returning the newly opened window on both cases, same as “window.open” does.

The isUndefined function in the code above is a function from my personal library. We’ll use a lot of code from this library hereinafter, and a trimmed-down version is provided at the end of the article and documented in the source. I find it very useful and I hope it aids your future scripting beyond simply popping up windows.

If all you need to do is pop up a couple of windows on a page or two, then this should be more than enough for you. If you plan to make heavy use of them (e.g. for an image gallery or maybe a CMS) and are not intimidated by JavaScript or the DOM, please read on.

Separate logic and presentation#section9

You probably hear it more than you’d like to: it’s important to separate logic from presentation. It’s true. In addition to a warm, fuzzy feeling, it gives you code that is easier to maintain.

So let’s take a look back into that HTML. There’s something in it that doesn’t belong there. What could possibly not belong to HTML? JavaScript! Out with the onclick thingie:

<a id="my-popup-link"
  href="http://example.com"
  target="_blank">pop me up

Now we must add event listeners to the “a”s that will pop up. To attach the event listener via JavaScript we add the following code to our script. Our script should be in the document head (either in an external script or in a script block):

function event_popup(e) {
  link_popup(e.currentTarget);
  e.preventDefault();
}listen('load', window, function() {
  listen('click', 'my-popup-link', event_popup);
  // ... other onload statements
  }
);

If we want to add an event listener to an element in the document, the element must be present in the browser’s internal document tree. When the document is finished loading, it triggers an event, load, on the window object. At this point, we’re sure the tree is complete and all elements are present. Here, we use listen to assign a function to this event, which will then call listen to safely assign event handlers to document nodes.

Listen is a cross-browser implementation of the DOM’s addEventListener(). It takes three parameters: event, elem, and func. To determine elem, it uses getElem, also from my library. getElem is a shorthand for document.getElementById with a special feature: it can take the element’s id, or it can take the element itself. It returns the element on both cases. Thus, elem can be either a string or an Element.

You’ll notice that we’re calling e.currentTarget and e.preventDefault, which IE doesn’t implement. A very useful feature of listen is that, in IE, it’ll wrap func and attach this wrapper to the event. This wrapper calls func passing it a faux Event object which will mimic these two features for IE.

Going wild with the DOM#section10

Adding a listener to an element via id is ok when you have very few links to pop up. If you have lots of links, it gets boring to code each listener one by one. For that reason, I present you with mlisten.

mlisten is the same as listen, but it takes an element list instead of an element, and adds the listener to every element on the list. The list can be a NodeList, or an Array of id strings and/or Element objects.

Here’s an example of using mlisten to pop up all links in a list:

mlisten(
  'click',
  document.getElementById('my-link-list').»
  getElementsByTagName('a'),
  event_popup
);

If your links are not structurally grouped, you can select them by their class using my function getElementsByClass(className [, tagName [, parentNode]]):

mlisten(
  'click',
  getElementsByClass('popup','a'),
  event_popup
);

The function handles elements with multiple space-separated classes well, so you can safely use one class to style the element and another class to denote behavior.

Remember, these calls should be made on the window’s onload event.

One small problem#section11

By using listeners, we’re unable to provide parameters to the functions. That keeps us from passing in individual window features to each link. Right? Not quite. Here’s a quick solution:

function event_popup_features(features) {
  return function(e) { 
    link_popup(e.currentTarget, features); 
    e.preventDefault(); 
  }
}// onload…
listen(
  'click',
  'some-link',
  event_popup_features('width=300,height=800')
);

There’s an important distinction to make here. Say fn is a function. When you write fn you have a reference to fn. When you write fn() you are calling fn and you have whatever it returns.

Here we’re using a function that returns a function. We’re not assigning event_popup_features to the event, we’re calling it and assigning the function that it returns. This function is like a personalized version of event_popup that takes into account the features we provided when calling event_popup_features.

The source#section12

That pretty much sums it up. Now that you know more ways to pop up a link than you ever wanted or needed to, feel free to grab the source code and the examples:

About the Author

Caio Chassot

Caio Chassot is a a web designer/developer and architecture student living in São Paulo, Brazil. He writes about code and design in his weblog.

130 Reader Comments

  1. Although one thing that you should make sure is that you tell the user that the thing will open up in a new window to ensure full accessibility. This can be done in the title attribute, so no need to mess up your text.

    There are some articles on the same topic around, and I once stumbled across this example:
    http://cookiecrook.com/include/popup.txt
    that seems to cater for every problem there might be with popup calls.

  2. sorry to the author but this is not one of the best issues, only one article and not that interesting… hopefully a new one soon

  3. “Sometimes we have to use pop-ups”

    Lies! Links sould only ever open in a new window when the user tells it to.

  4. Maybe for regular web pages, Eric. But web apps have other behaviors and requirements. Some of which are to protect the user from themselves. Pop ups are very effective for surveys, quizzes and forms. By removing the crome, users can focus on the task at hand. There is no “one way.”

  5. Wrong, in my humble opinion, is: “Sometimes we have to use pop-ups”.

    But right is: “we might as well do them right”.

    If, for whatever reason, you’re going to use pop-ups, do them right. And this article is a very helpful resource for those rare cases.

    Still better is not to use pop-ups at all. I have not stumbled across one single site yet that uses pop-ups that could not have been replaced by some kind of server-side-technology. So my suggestions would be: put some effort into finding a solution without pop-ups first, before you put some effort in doing them right.

  6. …I’d use this script:
    http://yayforgecko.net/newWin.js

    The code is cleaner and more semantic, and all you need to do is add an external class to the links you want open in a new window. It could be further modified to change the features of the window too. As far as I know it works in current browsers.

    I still don’t like opening in new windows, and I can’t think of a use where you’d really need the functionality of _blank. The only time I really like popups is if I’m at an online store and there’s a larger picture that opens in a popup. That I’m okay with.

  7. …I’d use this script:
    http://yayforgecko.net/newWin.js

    The code is cleaner and more semantic, and all you need to do is add an external class to the links you want open in a new window. It could be further modified to change the features of the window too. As far as I know it works in current browsers.

    I still don’t like opening in new windows, and I can’t think of a use where you’d really need the functionality of _blank. The only time I really like popups is if I’m at an online store and there’s a larger picture that opens in a popup. That I’m okay with.

  8. From a usability standpoint that may be true. But try and convince marketing folks that it’s ok to let users leave the site via a link. In some cases using popups is the only way to assuage concerns about site “stickyness”.

  9. I don’t really see how opening a new window helps them. It keeps them on your site, but it gets people confused. There are 2 windows to deal with, erasing tabs and making it hard to navigate between the two. If you’re concerned about people not knowing when they leave the site, use the little exit site icon found on a few websites, such as http://www.dithered.com/

  10. One consistent use I have for pop-up windows is viewing Flash, video, or multimedia presentations. This is useful because, when you open a new window, the user understands that “this new thing is different and unique” and it’s not necessary to build the parent sites’ branding elements around it to ensure consistency.

    When the user is done, hey, just hit the close box/link and you’re good. This is only one use case that is logical and users appreciate – another might be a larger view of a thumbnail image, for example.

    Users don’t inherently hate pop-ups. Its misapplication and pop-up ads are what users hate.

  11. “But web apps have other behaviors and requirements.”

    I can’t agree/disagree here because I am unsure of how a web-app differs from a regular page with an html form.

    “If, for whatever reason, you’re going to use pop-ups, do them right.”

    Agreed, although I have yet to find a situation (other than being forced by superiors) where using pop-ups is a good solution.

    “But try and convince marketing folks”

    Point taken.

  12. Web applications have different UI requirements than other type of web sites. In a business environment where people are trying to accomplish certain tasks, like entering data or web training. Also universities running online courses. Web browsers are a fairly difficulty medium for data entry and pop-ups can be a good aid in complex data activities.

    This is not about being forced by superiors. Its about creating a usable environment. Do your desktop apps run in only one window? There is more to the internet than just reading and buying stuff.

  13. This article isn’t telling you to load external links from your blog in a new window. It isn’t telling you to load blog comments in a new window. I agree that those practices can be annoying.

    This article is for the many professional ALA readers who build ecommerce sites and web apps.

    Here’s an example. I’m buying concert tickets. Or airplane tickets. There are terms and conditions associated with the sale. Before I can complete my purchase, I have to check a box that says I’ve read, and agree to, the terms and conditions.

    “Terms and conditions” is linked.

    I *expect* those terms and conditions to load in a popup window.

    If they don’t, I’ll be afraid that my data has been lost.

    This fear is based on 10,246 experiences on incompetently-developed ecommerce sites, where loading new data in the same window causes all my existing data to be lost.

    If the terms and conditions load in a new window that assumes focus, I know that my data (including credit card and other sensitive info) is still intact.

    When I’m finished reading the terms and conditions, I close the window, check the box, and conclude my purchase.

    This is just a very simple example of a case where a popup is not only okay but actually preferable.

    This article tells how to ensure that popups are accessible when you really, truly, absolutely need to create popups.

    That’s all it’s about and it does the job well.

  14. “I *expect* those terms and conditions to load in a popup window.”

    But you have no way of *knowing* whether they will or not in a consistent way. You can always “open link in a new window” and know what will happen. If you had 10,246 experiences of losing your data wouldn’t you start to open inks in a new window by hand? That’s the only wat to keep it consistent.

  15. I own and operate an e-commerce website, http://www.furnitureshed.com, and on we use pop-ups to display cloth swatches for our many different cushion colors for our furniture. The pop-up window is activated as a link by the user and is invaluable since it allows the user to stay on the item page while still picking a color for their cushion.

    Another example: At Ticketmaster I don’t want to leave the page I’m at just to see an arena seating chart. A pop-up is perfect.

    Used wisely, pop-up windows can be extremely helpful and easy to use. Thanks to Caio for writing this article.

  16. Eric,

    I hardly ever implement popups in my designs. When browsing, I do open new windows (actually tabs) manually. I’m also considering fully disabling the ability of pages to automatically open new windows. But that’s just me. You and I, and most ALA readers, we’re power users, we have greater knowledge of the browser features and use it to our benefit.

    Most web users won’t bother manually opening a link in a new window. Many don’t even know they have control over where stuff opens. Because we are developers and work with this stuff, we know that a whole lot can go wrong. But ordinary users expect things to just work.

    One of my first motivations on writing this article was having somewhere to direct the designers of sites I visited where I ctrl+clicked a link only to find a javascript:something in the new location bar. (The second usability issue I mention in the article)

    Your question about consistency, about not knowing whether or not the link will open on a new window, is a separate design issue. A “new window” icon as some sites use would do. Even a simple “(this link will open on a new window)” text warning would solve in the “Terms and conditions” case.

  17. How many average users do you know who will right-click on a link to open it in a new window? In the user testing I’ve seen, only savy power users were even aware of this option.

    When users feel lost, they either hit the back button or close the browser altogether and start all over. The chances of them coming back to a site that mislead them are very slim then. Used properly, popups can enhance the user experience just as much as improper use can impede it.

  18. Radley,

    I have no opposition to you using another script, but if you want to use mine with the simplicity of just adding a class to the elements, you can use the code given at the article:

    mlisten(‘click’, getElementsByClass(‘popup’,’a’), event_popup);

    If you add that by default to your script, every link with a class “popup” would pop up.

    Regarding the script you suggested, it “takes over” window.onload, so if you needed to add different things to onload, they’d conflict. It’s safer to use an event listener.

  19. This was actually *more* than adequate. That’s pretty rare for A a JS article on ALA (except for the image gallery). No offense.
    But you’re making it too complicated. It shouldn’t take an entire article to explain this.

    Overall too complicated but nice.

  20. Returning false without checking to see if the new window exists can fail in browsers like Mozilla (not Firefox) where there is an option to “block all popups,” not just “block unrequested popups.” That’s the reason for the scripts posted in the 1st and 7th comments.

    http://cookiecrook.com/include/popup.txt
    http://yayforgecko.net/newWin.js

    Incidentally, I’m not the same James that wrote the less-than-helpful 3rd comment. 😉 Hopefully this one was helpful. Cheers.

  21. James,

    I tested thoroughly in Firefox and assumed Mozilla would be fine. Guess not. The script can be easily fixed, and I guess it’s probably worthy it.

    So I’ll contact ALA and see what can be done about updating the article.

  22. When I started surfing the net (around 96 or 97) it was quite common to use the right click to open a new window. Decision was on user side. Then, I don’t know how or why (was it due to frames’ targets? Adds?), everyone relies on either javascript or target to open new windows, and people got lazy enough to forget about the chances they have. Opening a popup for a bigger image is ok. Opening a popup for terms and conditions is ok. But most of the times I will want to decide where to open links. Abuse of target or javascript pseudoprotocol has caused people to forget about our chances as users. If I want to open a new window to follow a link, I will. Don’t worry, if your site was interesting enough I still have the back button. Abusing the target is bad, but using the javascript pseudoprotocol to open popup’s is evil, as explained in this ALA article. But lets discuss the methods.

    If in the need of using a new window we have some options.

    1. The “excuse” of the lack of target validation in newer DOCTYPEs is not enough. You’re most likely talking about XHTML strict (or 1.1). Since it’s eXtensible, you can add your own module, or adapt the target module as provided in other DOCTYPEs. This way you have the functionality and the validation (if that matters to you). I learnt this from Mariano at http://www.byklein.com/ who arranged this little example (I keep a copy here: http://meddle.dzygn.com/tests/targetblank/) following an intersting discussion at http://www.domestika.org/foros/viewtopic.php?t=19583 (in spanish)

    2. Or you can simply ignore validation and use target easily.

    3. But my argument is: as a user, (most of the times) I still want to decide. A simple preferences page where I could choose whether or not I want to open external links in new windows would store a value in a cookie. Then running a script like this would suffice (if suffice means bypassing xhtml strict validation): http://meddle.dzygn.com/tests/targetblank/retarget.js This script uses the DOM to check for external links and adds the target using javascript. This is done either automatically or if a cookie has the accepted value. Execution relies on event handling, so it doesn’t interfere with any other onload events you might have. And since it used a proper namespace, it’s likely you don’t have same function names in your code. You need no markup in your html and user can choose.

    4. A special case would be those windows that should be open in a new window with special properties. The solution presented in this article is acceptable. Not bad, not new. Aaron Boodman and Scott Andrew already told us several months ago (2 years now?). I would probably prefer the following, but yours is ok too:
    alistapart

    If you’re not really in the need of using a new window, we still have some options to make navigation more pleasant. For instance, let users know a link is external by adding a little image next to it. You can use a similar approach as the script above, but adding an image inside the a tag, or use CSS, something like:

    a[href^=”http”] {
    padding-right: 10px;
    background-image: url(external.gif);
    background-position: right !important;
    background-repeat: no-repeat;
    }

    The user would have to use right click (or use the tabs options) to open in a separate window/tab, but he would be prevented. I mean, this is just presentational, but combined with the target module in point 1 or a script similar to point 3 or 4 it’d work fully. From my point of view, for most of the current sites, this CSS only approach would probably be the most elegant solution.

  23. Problem is that IE has no support for the ^ selector (nor !important). I can sympathize; it’s CSS3. In May I’m going to start a CSS3 Tests Site.

  24. Under the heading “Separate logic and presentation”, the code line:

    listen(‘load’, window, function() {

    appears to be missing a closing parenthesis.

    Rad article though, I look forward to delving into you library.

  25. listen(‘load’, window, function() {
    listen(‘click’, ‘my-popup-link’, event_popup);
    }
    );

    It’s not missing a closing parenthesis, it’s passing a function as its third arguement. On ALA the parenthesis is difficult to discern from the curly braces, it’s easier to read the code if you paste it into notepad. Formatting it in the way you usually format your own code makes it easier to understand.

    I was confused the first time I looked at it too.

  26. Jacob, that article is bad for some reasons, including code is not scoped and onload event overwriting your other onload events, to mention just two of them.

  27. Why is target deprecated? You need it if you have a framed site like mine. Why does the W3C keep deprecating rather useful tags and attributes?

  28. Caio, very useful and practical, thanks. And ALA, once again, seems to read my mind as to what could help me out right now and bring up a relevant article. Thanks, too.

    Others mention that there is no need for pop-ups, but if you’ve worked on this business for a while you know there is a place for everything. As always, the comments are good to gauge peoples views and find related resources.

    There is one issue I found with the code when run under IE6. In the example page, the 2nd, 3rd, 4th and 5th boxes bring up an error: Line: 18, Error: Invalid property value.

    As a developer I have unchecked “Disable script debugging” and checked “Display a notification about every script error” in IE’s options. This error will probably not show up if I had those settings the other way around, but I’m still interested in knowing a fix, or lacking that, what is exactly causing the error.

  29. Ohh I feel stupid for not thinking of this before:
    Javascript Image Gallery + Popups
    I think thumbnail images that produce popups of full-size images are a great use for popups. I’m going to write a script for just that. Here’s what I think it would be like:

    Call it like this:

    I'm going to also write a script that asks the user whether they want to open the image in a popup or follow the link.

  30. Target is not deprecated. It’s simply not present in strict doctypes. Strict markup should only define document structure and semantics. Target defines UI behavior. If you want to play with UI behavior and other things that do not relate to structure and semantics, you should use a transitional doctype.

    There’s a mindset that to be the uber cool standards guy you have to use the geekiest doctype of all. that would be xhtml 1.1 strict. but really, you should just use the doctype that best suits your needs. going transitional doesn’t mean you’re a bad designer, it just means choosing the right tool for the job.

  31. Dante,

    “Asking” (as in prompting) the user whether to open a new window or not may not be the best approach. You could use a checkbox “open links in new windows”

    And then you could attach something like this to their click events:

    function(e) {
    document.getElementById(‘popup-checkbox’).checked || link_popup(e.currentTarget) || e.preventDefault()
    }

  32. Here’s a quick fix for the issue with Mozilla blocking all popups config. I couldn’t actually find this configuration in Mozilla, so it’s untested, but there’s no reason why it should not work.

    function event_popup(e) {
    if (link_popup(e.currentTarget)) e.preventDefault();
    }

    function event_popup_features(features) {
    return function(e) { if (link_popup(e.currentTarget, features)) e.preventDefault() }
    }

    Or, when you’re using the script inline in the html event attributes, instead of simply returning false, return the negation of the return value of the called function (be it raw_popup or link_popup):

    pop me up

  33. To better demonstrate the reuse of named target windows, I made this little script that changes the backround color of the popup page based on the value passed in the url query string:

    listen(‘load’, window, function() {
    getElem(‘img’).style.backgroundColor = ‘#’ + location.search.substring(1);
    });

    but for the links that do not involve the named target windows, I didn’t provide a color value in the query string. That’s what’s causing the error. I should have first checked for the presence of the color value in the query string before trying to change the element’s bg color.

  34. i stopped reading the “got sth to say?” posts at the end of second page, as the discussion got off topic as for me. everyone talks ’bout using/no using pop-ups on their sites, whereas almost nobody talks ’bout the article itself. why?

  35. I like that. Good thinking.
    function showImg() {
    if (document.forms[0].elements[“win”].checked) openPopup();
    else top.location.href=this.src;
    }
    and then give the image their event handlers.
    I’m too tired to write the whole script now. Later.

  36. Nice article, it would have saved me some hours work if it only came one year earlier.
    Here’s another hint i often make use of:
    You may use different URLs for Popup and href; if you use server-side scripting, you may call “image.php?win=popup” or just “image.php” in the href attribute. Now you can implement a javascript-close-action or link back to the previous page, depending on the type of the new window.
    And keep in mind, that there are lots of popup-blockers out there nowadays; but they usually follow the href.

  37. As Caio writes, ‘target’ isn’t deprecated (bad choice of words there, sorry), but it’s not allowed in strict doctypes. In frameset it’s not only allowed, it’s necessary.

    I think using anything but strict doctypes is using abuse of markup, as the separation of structure and style is a really important issue. Maybe it isn’t important for others, but it’s either way *not* abot being über cool or geeky. It’s about following standards and guidelines, set down by those who made HTML; W3C.

    And Caio; there’s no such thing as XHTML 1.1 Strict. It’s either XHTML 1.0 Strict or XHTML 1.1 (which is strict and has no alternative DOCTYPEs).

    Creating custom DTD’s isn’t really a solution to anything. Let’s try to find the best solutions there are with the tools we have (W3C’s standards), and follow up on those. I don’t hate popups; they have their usage, but there’s no point in creating non-strict markup when you can do the exact same thing with valid strict markup.

    I know http://www.sitepoint.com/article/standards-compliant-world dosn’t have the best code in the world, but I actually think the solution is better than the one presented in this article. Sorry.

  38. Asbjørn,

    “Creating custom DTD’s isn’t really a solution to anything.”
    What does the X in XHTML stand for? eXtensible, right? 🙂

    And, when I said the article at sitepoint is bad for some reasons, I still think so. The article presented here at ALA is much much better. Sitepoint’s article has some cons:

    1. onload event overwriting your other onload events. this is probably the worst point, since it will interfere your other scripts for sure.
    2. code is not scoped: you could not mix with your code safely, you could overwrite function names, etc.
    3. using rel=”external” needs extra markup in your html. If javascript has to be used, all you need to check for is document.domain in the href
    4. if you’re *not* asking your users whether or not they want to open external links in new windows, *then* i think extending your dtd is your most elegant solution, since setting the target through javascript is merely a hack to make sure your page validates.

    These are just my opinions though 🙂

  39. Haha. That’s a good one.
    Strict doctypes are the way you want to go if you don’t want backward compatability. I don’t use doctypes at all. What an evil web developer I am.
    Seriously though, if you want the bleeding edge with XHTML go ahead. I don’t see how it’s extensible though.

  40. Well, if in strict doctypes the (X)HTML is for structure and CSS is for presentation, and if opening in popups counts as presentation, perhaps CSS should offer some of that functionality?

  41. I work at a company where someone set up pop-ups using javascript: in the href. Besides all the problems described here, I’ve found it’s a mess when trying to programmatically changing all links on a site.

    For instance, if you want to change popup.html to new.html, I would normally search for href=”popup.html”. But, this gets busted up. I confused programs like GoLive and Dreamweaver, too.

    By using ‘this.href’ in a function and having the href be a real destination, this problem is solved.

    Good article and good reference for the future.

  42. Just consider some users, which do not even have such things as windows. I, for instance, use a frame-based window manager under Linux and every single browser window is opened full-screen. I’m really not amused about the whole pop-ups which only feature a small text about something completely irrelevant. I’m also not amused about the comments of some of the webdesigners, when I tell them they have too much surrounding yellow color in the page, they tell me “It’s no problem, the window will auto-size itself”. User having windows on the desktop is just a wrong assumtion!

  43. As I wrote, Sergi, I know the code in that article isn’t perfect. But it gives a better solution than this article does, imho. It’s standard compliant, and extensible for anyone who wants to extend it, and anyone could improve it easilly. Maybe I will, and write and article about it.

    And the extensibility in XHTML doesn’t lie in changing the DOCTYPE. Creating custom DTD’s is something you’ve been able to do since the birth of HTML some 12 years ago. The extensibility in XHTML lies within namespaces; you can create custom tags and attributes just by specifying a custom namespace (prefix) for them. Both custom DTD’s and tags present the same problem, though; nobody else but you understands what they mean, unless your DTD and/or tags get widely adopted.

    And Strict DTD’s aren’t new either. They’ve been around since HTML 2.0, which is 10 years old. The point of using them, in both XHTML and HTML, is to try using HTML for structure and other means (e.g. CSS) for presentation. Behavior is typically a job for JavaScript, not HTML, hence the removal of ‘target’ in XHTML 1.1 and in all Strict DTD’s. Using strict DTD’s doesn’t give you worse backwards compatibility, it actually gives you better! It enforeces pure structural HTML which *every* browser in the world understands. It’s the CSS applied to it that might break backwards compatibility, but that’s not an issue here, because CSS has nothing to do with HTML in this context. It’s the content that matters, isn’t it?

    People can and should use what they want. But they not call those who try to enforce W3C’s recommodations and separate structure from presentation and behavior «geeks», «uber cool standards guy» or someone who has to be at the bleeding edge. Why? Because this isn’t something new, and just because someone hasn’t discovered what a DOCTYPE is yet, doesn’t make everyone who has, übger-geeks or self-righteous and patronizing bastards, right?

  44. Asbjørn,

    When I made the comments about uber coolness and geeks, I said there was a mindset. And a mindset there is:

    I’ve once showed my site (xhtml 1.0 transitional) someone and he answered back with a “hey, look at mine. it’s strict”, with an air of “I’m such a better coder than you are”.

    Indeed his site was strict. But it was entirely built up of divs and spans. No semantics at all.

    It doesn’t mean everyone who uses strict does it to look good. Perhaps, and most probably, strict is just what they need. But when you see people working on custom DTDs and stuff like that just to add to the language something that is already in it (albeit in a different doctype), that’s soemone trying too hard to stay strict, when what they need is something else.

    The point I was trying to make is that using a transitional doctype is equally standards compliant to using a strict one. If there was no point at all in using a transitional doctype, than transitional doctypes wouldn’t be issued with the specs.

  45. Caio,

    I think we agree. I don’t see as much need for Transitional DTD’s, and I don’t think ‘target’ is a good reason to drop down the notch from Strict. If Strict is the upper goal, why stop reaching for it just because you want functionality that doesn’t validate?

    I think it’s better to try to stop using functionality that breaks the validation, and rather sit down and think for a while. I was very reluctant to stop using ‘target’ myself, until I realized users would come back either way if they liked my site (every browser has a back button), and creating windows for the users only confused them.

    So, many users might not have the knowledge to open new windows. Well, it’s not our job to do that for them, I tell you. They will always be able to go back, and they will find the necessary information without us forcing it upon them.

    Popup-windows have a slightly different range of application than ‘target’-windows, especially when used for small, informative texts and such. Here I think using JavaScript is OK, though I presonally still prefer opening windows myself. The article I’ve pointed at a couple of times now shows how you can have strict markup and still get popup windows, and I fail to see why that solution is worse than using ‘target’.

  46. Asbjørn,

    My script also works without using target, you can use strict doctypes with it fine.

    It only requires target if you’re using named windows, or to cause new windows to open for users without javascript.

  47. I’d like to represent the Lilliputians in the audience. I am a glorified copy and paster. I’m trying to keep up; honestly I am. I have a page that uses popups to display close ups of fabrics used in the most-interesting ScubaDoRags. I also use them for links. I did so to preserve stickiness. I can see that everyone here is anti-the-stickiness. I’m curious to know if the aversion to this argument is quantifiable, or if its the frustration of veterans like yourselves. I don’t wish to be maimed or ice-picked; but, I’d like to hear some ideas from user-based research rather than opinions. Of course, the stuff on which I’m working is not intended for a geek crowd (I use the term geek affectionately). If I were to target (couldn’t resist) a more educated bunch, I’d endeavor to remove the external links. Let’s say I’m undecided and need some empirical evidence to support the anti-sticky claims.

    Thanks,

    B

  48. i don’t want to get totally laughed at (again) but is using onClick really an acceptable method. i thought we were meant to be staying away from anything ‘click’ specific and consider any method for selecting the link ?

    feel free to enlighten me as i am clearly missing something ?

  49. Burt: You’re missing the bit of the article headed “A note for accessibility aficionados”. OnClick works for the keyboard too (apparently).

    Benjie: Apart from winding up power users, unnecessary new window opening can cause accessibility problems – see http://www.fixingyourwebsite.com/DiveIntoAccessibility/day_16.html for why. Using new windows for “stickiness” is just an illusion. If I want to leave your site, I will. If I want to come back to it, I can (except, oh dear, your new window just broke my [Back] button – so maybe I won’t find you again). Trust your users to know what they want to do, and don’t get in their way when they do it.

    Asbjørn: There’s nothing (IMO) intrinsically better about strict doctypes than transitional ones – any more than english is any better or worse than french. It’s useful to declare a DOCTYPE, and sensible to stick to it when you’ve done so. Furthermore, I don’t see why this is unspeakable intermixing of content and behaviour:

    but this isn’t:

    You’re still hard-coding an attribute into each link aren’t you?

  50. Although I wouldn’t use popups, this article is very interesting for providing a HTML-only way of using onclick handlers. For example, I needed to have a link that linked to one page if JS was available, or another page if not available. Problems I came across…

    1. Using SCRIPT to generate a link to a JS-page, and NOSCRIPT to provide the alternative link doesn’t work, because in STRICT doctypes the content of NOSCRIPT has to be block level and this disrupts the flow of the page content (if the link is in a list item for example).

    2. Using causes Bobby to fail the page at WCAG level 2, because it thinks the link is inaccessible to keyboard users. It isn’t. If their browser doesn’t trigger onclick by pressing Enter then they just get the non-JS link instead.

    3. Putting onkeypress into the link, with the same JS content as onclick, satisfies Bobby, but makes any content below the link on the page inaccessible, as Tab is regarded as a valid keypress to activate the link (except in IE – another reason to ditch IE).

    It didn’t actually occur to me that the onclick handler could itself be added to the link via Javscript, leaving the HTML clean and tidy.

  51. “2. Using causes Bobby to fail the page at WCAG level 2, because it thinks the link is inaccessible to keyboard users. It isn’t. If their browser doesn’t trigger onclick by pressing Enter then they just get the non-JS link instead.”

    c’mon… in this case, Bobby is obviously broken. That is no reason not to use the syntax. It has been pointed out on many sites, not the least of which is zeldman’s, that Bobby is sometimes straight-up wrong.

    We should be designing/developing web pages to solve problems – users’ problems – not to cater to obscure bugs in validator code.

    “1. Using SCRIPT to generate a link to a JS-page, and NOSCRIPT to provide the alternative link doesn’t work, because in STRICT doctypes the content of NOSCRIPT has to be block level and this disrupts the flow of the page content (if the link is in a list item for example).”

    I feel the same way about this, though I recognize it’s a little harder to justify (which is why I put it second). The script/noscript solution is very elegant (I use it myself quite often). It works in every browser I have tested, and is a *defacto* standard which can be counted on to work more often than strict doctypes themselves!

    Just my opinion, but in all but the most extreme cases (erm, library websites, government websites, etc), if you’re working to solve *user problems*, then you will put an elegant solution which works in every browser ahead of a cheesy solution which caters to a poorly-supported standard.

  52. > c’mon… in this case, Bobby is obviously
    > broken. That is no reason not to use the
    > syntax.

    Absolutely – which is why I’ve left it like that with a disclaimer that I’m still claiming WCAG AAA accessibility even though Bobby fails it!

    However, this article has given me the way of stripping the HTML source of all Javascript AND satisfying Bobby at the same time!

  53. Can someone please advise: which method described in the referenced article would be best for the following purpose: I wish to have a visitor come to my web page, click on a link on the page that says “photo,” and have a photo of the item appear in a small pop up window. Thanks.

  54. Well, I take the point. Still, I’d be interested to see the results of some sort of usability survey. I got a book for my birthday: The Design of Sites
    http://tinyurl.com/282g2.
    I haven’t crawled all the way through it yet, but the authors advocate a user-centric rather than designer-centric approach. So, that’s really the source of my query.
    You guys are the masters, however, so I do trust your opinions; heck, it’s why I’m here.
    Thanks,
    B.

  55. I think its a good article and a good JavaScript. Not perfect, but at least as good as any other present solution!

    Personally I’m interested in your library, I’ve been looking at cross-browser script libraries to avoid needing to repeatedly compensate for browser differences, and I’ll be taking a look at you library soon.

    ——–

    DHTML pop-ups are what I’ve used in the past, but obviously that can cause many more problems.

    Whoever said we should not try to control presentation is wrong. We can’t trust the browser or user to be able to interact with our pages in the most efficient or effective way. The only problem arises when ‘far from average’ users CAN’T access the content or function, as long as it is still POSSIBLE for EVERY user to use my web site then it is OK to add more usability for a subset of the users.
    As ‘far-from-average’ users are in the minority, no user-focused designer would sacrifice good usability for the sake of a few.
    Did God make the world flat so that everyone could got the same experience out of it? No.

    Er anyway what was I saying? Oh yeah…
    If pop-ups add value, then I will use pop-ups. If they can be implimented with no negative affect on ‘far-from-average’ users, then that’s how I want to impliment them.
    So, good article!

    ——-

    I presume the use of having a DOCTYPE is so that computer programs and other non-human web browsers know what html/xml tags are being used and what attribues/values they can have.

    The biggest problem with DOCTYPEs is that IE stops working in any predictable way. (IE’s quirks may be annoying but at least when it is in ‘quirks mode’ we can predict problems and take evasive action! Although I had hoped IE in strict mode would behave better and more predictably, I have not seen it do so yet).

    ——

    Here’s an example of when using eXtensibility in documents is good…
    meta-data is meta-data, it is information about information, why should we limit ourselves to the types/categories/headings of meta information that the W3C predicts to be a general range of good attributs for everyone?
    Each web page is different, if you need to break the mould, then do so! (The W3C aren’t stupid, they made sure the functionality exists – custom DTDs).

    In many cases I have HTML elements that have a peice of info specific to that element, where is the best place to put that info? answer – In an attribute of that tag!

    It may not be standard but it’s useful for that element.
    For example, if I want some abitary images in my page to change when the mouse hovers over them, I will write a generic script that swaps images, but because each image using that script needs to have its own individual hover-state image, I record the hover-image src in each individual IMG element:

    Now in my behaviour layer I can make a script that swaps image “src=” with the “hover_src=” if/when it exists on the element.

    Another example can be seen on my site:
    http://www.alpha-matrix-design.co.uk?section=contact
    Each form field has attributes providing specific information on how to validate its value.
    My custom attribute “validate_pattern=” contains a regular expression pattern, which is used by my JavaScript to test against the “value=” value of the field.

    I hope you agree these are good uses of HTML. In addition they do no harm.

  56. Caio Chassot wrote:

    “My script also works without using target, you can use strict doctypes with it fine. It only requires target if you’re using named windows, or to cause new windows to open for users without javascript.”

    Another option for named windows would be to use element.setAttribute() for the target attribute of the anchor, but this essentially does the same thing the JavaScript would do with the name parameter of the window.open() method. It still wouldn’t open a new window without JavaScript, but that’s probably a good thing. 😉

  57. James,

    If we’re using javascript, the target attr is only used to grab the name of the target window, hence to set it, we would already need to have the name, but the name would be read from target… so you get the point.

    If you can’t use target and still need a named window, the best option is to use a similar attribute in a custom namespace, and addapt the script.

    regarding the comments that say using a custom attribute from a custom namespace is useless because unless you’re using a popular format, machines will have no use for it:
    I agree that there’s no point, for example, to invent a new way to mark up content and hope the web to make sense of it, but the attribute in question is only useful to the behavior script which we have full control of. It’s a local use attribute. It has no deeper meaning that would somehow empower thee semantic web and stuff. So in these self-contained cases we’re free to come up with whatever we want.

    LazyJim has a good example of using custom attributes, although he fails to use a custom namespace for them.

  58. David,

    All methods are fine. If it’s just a single link and you want to have it solved quickly, the inline link_popup code should do it:

    photo

    If on the other hand there are plenty of photo links, the “Going wild with the DOM” examples are more scalable and a better fit.

    I guess, in the end, evaluating which method will work best with your situation is a task better handled by yourself.

  59. Would doing something like this work?
    Popup
    Not saying you should use it, just wondering.
    I understand ALA published a really bad article about Accesskeys. In my opinion it was the worst article ever.
    Oh and if you stick to Quirks Mode you don’t need a namespace.

  60. Pop-ups, like message boxes, are evil and should be banned from this planet.

    Evil I say, just plain evil.

  61. javascript isnt necessary for new windows as has already been mentioned, just use the modular XHTML 1.1 dtd with the target element included – problem solved

    the only time i feel that js is useful is for a flash presentation or something which opens in a new window of a set size in which case js is the only way to control that, otherwise just use the XHTML thats there and stop coming up with fancy workarounds for problems that dont exist

    all IMO of course

  62. It’s nice to be shown how to use techniques like these properly. If for no other reason then to broarden our understanding and to know that it’s there to use should we require it. It’s all about usability. If your going to do the time, you might as well commit the crime. I know many people hate popups but you should never write anything off totaly. You never know when you may need it.

    FYI In England and we spell Color with a u.

  63. I personally hate popups, but they are very popular (only God knows why) with the graphic design community. Maybe this article will at least help them make popups a little more accessable.

    Now I have a place to point to when someone asks about popups. After they hear my “I hate popups speech”, of course.

  64. Dante,

    The accesskey thing worked in Firefox with the article examples page.

    (Tested doing a quick hack with jesse ruderman’s jsshell. Since jsshell won’t run in a page context in IE, I didn’t test it)

  65. Thank you for replying Caio. I should have mentioned that I have at least 100 such photo links scattered amongst 12 pages. Would you be so kind to explain to me how to use the “going wild with dom” functions for more than one link? Your article is quite advanced and over my head. Thanks.

  66. Hi, I like this script (so sue me). But is there a way to make the visited links change to their visited colour immediately? They currently don’t on my setup (IE 6, Win 98).

  67. Thanks for the fix on line 18 – invalid property value. I am getting another error: Line 160 – Exception thrown and not caught. This in IE (6) of course – not NS/Firebird or Firefox. Thanks.

  68. This is a great article, even though some may find it boring. Popups are one of the simplest things that people absolutely butcher. I think 90% of the value is in the first half before you even go into the Javascript madness.

    An unmentioned benefit of using (this) in your function is that link validators/checkers will spider the one href link and you are still covered on the javascript link – as opposed to including a seperate url in the onclick like I’ve seen done often.

    But in the end, popups should and can be avoided. Just like frames. But with all the third party popup killers, Opera 6’s horrible popup-killing behavior, and the option in many browsers (IE 6 : WinXP SP2 included!) to turn off ALL popups including those initiated by a user click, relying on popups in anything short of a tightly controlled environment (Intranet) is even worse than using frames. Anyone can get around using either with some creative coding.

  69. david, why don’t you explain where you got stuck or what specific part of the article/script you don’t understand?

    i’ll give a brief description of the stuff involved…

    to add a listener to a bunch of links you use mlisten, it takes as parameters an event name, a list of elements to attach the event, and the function that’ll handle the event:
    mlisten(‘click’, my_img_links, link_popup)

    you’d call mlisten inside the window load event function (see source code of example page for an example)

    to generate the my_img_links var I’d need to know the structure of your document. a safe way would be as I do partly in the examples page, add a “popup” class to each a element. a more savvy way would be to grab the element that contains the links, then get the links:
    my_img_links = document.getElementById(‘my-links-container’).getElementsByTagName(‘a’)

  70. What is the reason the TARGET attribute is deceprated in xHTML Strict? I really don’t get it, we are there to provide user friendly environments to our visitors and customers. They don’t even know you can Ctrl + Click a link (or Alt + Click) to open it in a new window/tab.

    The reasoning was what? They need to decide for themselves whether or not they want a new window? Isn’t that more of a BROWSER feature, and not something to limit me in?

    Sounds equally rediculous to me as removing LINKS all together, just because someone might not want a link at that location where you put it – instead you are to provide an external page with all links in it, that the browser will read and put in a nice overview.

    The solution is nice. But the problem is… dumb.

    Re: Frames:
    Frames are not necessarily bad, it’s just not the fashion this year 😉

  71. It’s depreciated cause it’s a behaviour – should be scripted rather than mark-up.

  72. As I see it, strict doctypes are meant to markup documents.

    A great part of the web pages we have on the web nowadays are not documents, they are application screens.

    Aplications have behavior specifications. Documents do not. And that’s why strict doctypes don’t have target.

    Now, using a transitional doctype is not the ultimate solution for coding web applications. Target is the least of our concerns when developing applications in HTML.

    The problem is that there’s no W3C sanctioned solution for web apps. Some like Flash, I find XUL delightful but unusable (moz-specific). In the future some SVG + JS could do it, although something more specific would be better.

    Ian Hickson is apparently working on bringing the lack of web app language issue to W3C’s attention:
    http://ln.hixie.ch/?start=1074466808&count=1

    I’m hoping something like XUL comes out of it, at least in regard to the box model and XBL.

    (Maybe with XBL we could create a XUL-inspired language implemented in SVG? Well, whatever, this is definitely not the place to discuss it)

  73. So putting presentation and behavior in HTML is bad but putting structure in CSS (element { content: url() }) isn’t?
    Tsk tsk. I’m not sure what web standards wants anymore…

  74. Hello Caio,

    Background info: In IE 6 win I have checked “display a notification about every script error” (not the default) and have enabled script debugging.

    When I click on the links at http://www.site-shack.com/test/ I receive the runtime error line 160 “exception thrown and not caught” — I am hoping to implement your very nice script on a client site, but am concerned about this error. Thanks for your help!

    Judy Wilson

  75. The problem boils down somewhere to getElem. getElem will throw if there’s no element having the id string you passed to it.

    You are probably not calling it directly, but perhaps via listen.

    Anyway, check to see if the IDs you’re passing are correct.

    The error throws in mozilla also, where you’ll get the thrown message: “cannot get element: element does not exist”. I mention this because you could use venkman (mozilla’s js debuger) to track down which exact call is causing the error. If you are not familiar with venkman, you can try loading the page isolating each suspect call via comments and watch the js console for the error.

  76. I was hoping there was going to be an alternative solution described here so that target=”_blank” wasn’t used when the DOC type is set to strict.

  77. I enjoyed this article because it showed us a nice, clean way to generate a pop-up window without all the nasty “onclick=javascript:…”
    mumbo jumbo. However, the “target” attribute of an anchor tag is not supported in XHTML 1.0 Strict, thereby causing previously valid pages to become invalid just by adding the attribute.

    I suppose I see the need for pop-up windows, but possibly the W3C doesn’t want them around anymore??
    The only available alternatives would be:
    -solely use listeners to capture the events and handle them (one of the examples does this)
    -use the tried and true technique of placing the function calling javascript in the HREF value.

  78. .. I guess that’s what I get for not reading all the thread replies first, didn’t see that my point is already being discussed.
    Sorry 🙂

  79. Am I the only one or is the Examples page faulty? The examples don’t actually work on any of my computers (one uses MSJVM and two are using JRE 1.4.2_04).

    Not to say the technique doesn’t work, the technique works just fine. I’ve been using it to build a nice web app since the article was published. The specific errors are a syntax error and “event_popup is undefinied”

  80. I’m using Win/IE6. I thought it was strange that the examples didn’t work, considering my own pages using the same code work.

  81. 1. a href=”foo” onclick=’this.target=”_blank”;’

    2. It’s valid XHTML strict, works on every 4.x – 6.x browser I’ve tried, doesn’t break Right Click/Open In New tab|window|whatever.

    3. Sometimes those of us who do care about web *applications*, actually *have* given this some serious thought. Browsing a document != using a thin-client application. A good case for separate windows is when viewing an Excel attachment, or reading a help page in the middle of a partly-completed non-trivial form. For many real-time applications which have to issue nocache directives, using the back button *will* destroy previously typed content. You don’t want a separate window/tab, fine. Finish the form, then click Help. But I think it’s foolish to assume that *most* casual business users are even aware of the right click option. If this is my audience, why would I intentionally put a link that would wipe out edited input?

    4. I like Zeldman’s idea of the web triumvirate:
    XHTML=structured content
    CSS=presentation
    JavaScript/ECMAScript=behavior

    Some folks seem to have a knee-jerk reaction to the third component from bad experiences with stupid DHTML-because-I-can design. But this is not 1998, and browsers are more than just content readers.

    Just my $.02 …

  82. This is not 1998, the last time I checked (unless I walked into a time machine).
    The days of flashy DHTML design are over. DHTML can still serve a useful purpose. The Behaviour layer can offer us amazing possibilities, and if some people don’t accept that that’s their problem.

  83. I am one of those asked to use popups. Unfortunately mine don’t work properly at the moment and I don’t see why. http;//www.flcc.org/e107/content.php?content10 is the address. Can I bug someone to take a look. It may just be that I’m tired and am missing something, but still help is appreciated. BTW This, and many other articles at ALA have helped me out quite a bit. Thanks!

  84. I think I see the problem with my modification of your code in Opera – I used mlisten but contrary to your example (with features), I used class rather than id. I would like to use mlisten combined with class because id shouldn’t be repeated on a page and I have a planned use for this popup which could be used multiple times on a page.

  85. I think I see the problem with my modification of your code in Opera – I used mlisten but contrary to your example (with features), I used class rather than id. I would like to use mlisten combined with class because id shouldn’t be repeated on a page and I have a planned use for this popup which could be used multiple times on a page.

  86. I think I see the problem with my modification of your code in Opera – I used mlisten but contrary to your example (with features), I used class rather than id. I would like to use mlisten combined with class because id shouldn’t be repeated on a page and I have a planned use for this popup which could be used multiple times on a page.

  87. Julian, I’m not sure what you mean. In the example page I use mlisten with classes:

    mlisten(‘click’, getElementsByClass(‘popup’,’a’), event_popup)

  88. One aspect of accessibility was overlooked and I haven’t seen reference to it in this forum – alerting the user that a popup link will open a new window. I tried to modify popup.js by adding title to the raw_popup function:

    function raw_popup(url, target, title, features) {

    and

    if(isUndefined(title)) title=’Link opens in new Window’;

    and

    var theWindow = window.open(url, target, title, features);

    and title to the link_popup function such as after ‘_blank’

    ,src.getAttribute(‘title’) || ‘Link opens in new window’,

    but I think I am missing something because I am not seeing the tooltip of with the title text. Maybe this is not possible, I don’t know.

    If anyone has a solution, please contact me at julian dot rickards at ndm.gov.on.ca.

  89. I think a better way to warn the user is to provide a small image as an indicator by the side of the link. That could be achieved with a[target=”_blank”] selector (of course not working in IE), or, if we’re using the popup class, with a.popup

    To use the title though, I don’t think the popup functions are the appropriate place to pass the attribute value. A better way would indeed be in the html itself , or, if it should be done by script, then it should be done by the time we assign the event handlers.

    So, say we have an array or NodeList of popup links called popup_list, onload we’ll have the following code:

    mlisten(‘click’,popup_list,link_popup);
    map(popup_list,function(a){
    a.title=’opens in a new window’});

  90. why not this code (as explained in page 3):

    a[href^=”http”] {
    padding-right: 10px;
    background-image: url(external.gif);
    background-position: right !important;
    background-repeat: no-repeat;
    }

  91. Got it!!

    Two variations:

    Variation 1:

    Adds the title attribute where anchor tags have class=”popup”.

    onload = function()
    {
    var i = 0, thislink, poplinks = getElementsByClass(‘popup’,’a’);
    while (thislink = poplinks[i++]) {
    thislink.setAttribute(‘title’, ‘Link opens in new window’);
    }
    }

    Variation 2:

    Adds additional text where anchor tags have class=”popup”.

    onload = function()
    {
    var i = 0, thislink, poplinks = getElementsByClass(‘popup’,’a’);
    while (thislink = poplinks[i++]) {
    var title_text = document.createTextNode(” [Link opens in new window]”)
    thislink.appendChild(title_text);
    }
    }

    Now I am going to try to see if these functions may be built into Caio’s lib.js

  92. Julian, I’d advise against directly setting window.onload, due to imminent script clashing.

    A better way to ensure script interoperability and concurrency would be to use listeners, by using the DOM’s “addEventListener”, or my x-browser wrapper “listen”. This way many scripts may assign different handlers to the same event.

    On an unrelated note and a matter of personal style, I’d suggest that you check out my “map” function, as I find it a much cleaner means to traverse a list and do something to it than for or while loops with an increment counter.

  93. I appreciate your comments Caio. I am for the most part, just a newbie at JS but I am able to understand what I have done. I use the word “I” loosely because it was with some help from another member of SitePointForums.com that I was able to put this together. The other person wrote most of the code and left it for me. I then tried it, found it didn’t work, using the Moz JS console, I deduced the problem, made the fix and offer it. If I have a look at your code (your skills are much greater than mine), I would go dizzy. However, what I/we have done is added a functionality (however poorly) that I felt was missing from your excellent application. As I have mentioned before, if you would like to take what I have done and incorporate it into yours however you feel it should be done, please do so.

    I personally would feel much more comfortable if either the title text or additional link text were added to the application. It fits in much better with checkpoint 10.1 of the WCAG which says (from my memory) that either don’t use popups or open new windows or if you do either, warn the user. Nevertheless, friends of mine argue against any target attribute or JS popups but others are not quite so opposed. For those, including myself, who take the more lenient approach, I feel that this one inclusion now raises this application up to the bar set by 10.1 of the WCAG.

  94. One more thing. I understand what you mean by event listener and most certainly, I can see how it applies to your original code: listen for a click, then run code. However, can the event listener be told to listen to onload? In the case of my first snippet of code, onmouseover would be sufficient to generate the title attribute because you can’t see the title text until the mouse is over the link text (in addition to onmouseover, onfocus should be accounted for too). However, in the second case, the modification of the link text would have to occur at load time.

  95. Julian, you can add a listener to onload, in fact, I do it in the article when I first mention my listen function under the “separate logic and presentation” section:

    listen(‘load’, window, function() {
    listen(‘click’, ‘my-popup-link’, event_popup);
    }
    );

    This listen block sets a function to be called when the document is loaded, which will then call listen again, this time to add the listener to a popup link.

    You probably could use the following code to add the title attribute:

    listen(‘load’, window, function() {
    popup_list = getElementsByClass(‘popup’);
    mlisten(‘click’, popup_list, event_popup);
    map(popup_list, function(a){a.title=’opens in a new window’});
    }
    );

    Regarding adding this functionality to the script core, it’s such a one-liner that I don’t see how it could be “integrated” into it, or how it would be advantageous, specially since I don’t provide specific means to add the popup handlers (we use the general-purpose listen), and thus cannot modify it.

    I guess you just type it when you need it. Or, well, we could just wrap the code I provided above in a function called add_listener_and_title_to_popup_class_links or something shorter.

  96. I joined this late… and I’m a marketer, not a site builder – so I get confused easily and I don’t pretend to grasp much of this.

    I’m going back for a re-read to better understand.

    Meantime, I’m looking for some practical clarity.
    Advice appreciated. Please and thanks.

    At risk of drifting off subject…

    As a marketer I need to advise clients appropriately.

    In liasing with their developers/staff, I often encounter ‘existing practices’ which are ‘perhaps not optimal’. An easily accepted simple example? …some enthusiastically use frames/tables. (Sadly, this includes webdevelopers delivering substandard service – either knowingly or through simple lack of awareness).

    My ‘problem’ is that as a sole practitioner, I have to cover a lot of ground – too much to have all-areas expert knowledge. There’s much I don’t understand and, in efforts to develop a working awareness, I spend a lot of time here – frequently getting lost in tech stuff way beyond my competence and interest.

    I got lost in this one very early on – and even more confused by 12 pages of follow-on. As I said ‘I’m going back for a re-read to better understand.’ And meantime, I want to know what to do – and no tpass-on poor advice.

    I tried the examples at http://www.alistapart.com/d/popuplinks/examples.html

    When clicked normally (on my aging IE5/OS9/Mac)…

    1-3 open new small window.
    4-5 open in main window.
    6-9 open in new full size window.

    When holddown/right click (intentionally open in a new window)…
    1 blank new full size window
    2-3 new small popup.
    4-9 new fullsize window.

    I’m guessing they’ll behave ‘better’ with more modern browsers on my OSX-equpiped laptop.

    Thing is though – only 2 and 3 work on a machine/browser combo still in common use. Do I use them and ignore the others?

  97. gulliver, apparently IE5/OS9 is having a problem with some code of my library that is relevant in setting up event listeners (perhaps it doesn’t support them at all, but I really can’t tell)

    So the short answer is indeed, stick to examples 2 and 3 if the popup behavior for IE5/OS9 is important.

    The long answer is that you can either get a coder to debug my library and find out what in it IE5/OS9 doesn’t like, or you can treat IE5/OS9 as an aging browser and let it fall back on the sub-optimal behavior that you describe: loading on a normal size (either new or same) window.

    Notice that letting this happen does result in an accessibility issue since the documents still open, even if not in the desired popup fashion.

  98. >treat IE5/OS9 as an aging browser and let it fall back on the sub-optimal behavior that you describe…

    Thanks, C. That’s sound advice and something I’m increasingly accepting.

  99. Hi:

    Sorry to burst your bubble, but this script is partly broken in Opera as I had first suggested but I couldn’t see the pattern. From what I was told after asking around, it is a built in permissions thing that Opera is more strict about and other browsers seem not to be as strict. Set a popup link to open a page from a different domain and both the popup and the main window will go to the destination.

    I don’t know JS so I don’t know if there is a fix. However, as long as you are creating popups from pages within your domain, you won’t see this problem.

  100. As a person who consistantly searches news feeds from a variety of sources, some using popups others not, I generally open new windows to view information.

    It is heartening to see people advocating pop up code that will allow me to do my traditional ‘open in new window’ actions on links that use javascript.

    Nothing more frustrating than opening the new window, having it fail, shutting that window down and clicking on the link normally.

    Here’s hoping everyone takes this up.

  101. Gulliver/Caio, some information i found concering event listeners and IE5/OS9 at http://developer.apple.com/internet/webcontent/eventmodels.html

    “If you plan to support IE5/Mac, you can dismiss the attachEvent() and addEventListener() methods because IE5/Mac supports neither of these.”

    There is only on way left to apply a function to an event (beside coding in the document structure):
    element.onclick = myFunc;

    I extended Caios listen function:

    function listen(event, elem, func) {
    elem = getElem(elem);
    if (elem.addEventListener) // W3C DOM
    elem.addEventListener(event,func,false);
    else if (elem.attachEvent) // IE DOM
    elem.attachEvent(‘on’+event, function(){ func(new W3CDOM_Event(elem)) } );
    // for IE we use a …
    else // IE5/OS9 elder browsers
    eval(“elem.on” + event + “= func”);
    }

    The examples all work fine now.

    Thanks a lot for your great article and the cclib.js!

  102. michael, actually the thing (handling ie5/os9) is a bit more complicated than that: the function handling the event will expect an event object, but when a function is assigned to handle an event via “element.onevent = fn” it element itself will be passed as parameter to the function, so we must use the same wrapper we used for IE/win:

    elem[‘on’+event] = function(){ func(new W3CDOM_Event(elem)) }

    (also see there’s no need to use eval)

  103. This was an excellent article, which demonstrated a lot of very usefull techniques, especially the listener model.

    And, yes, I’m one of those users who usually opens up links in new windows and gets REALLY frustrated when some lame webdeveloper has javascript’ed their links.

    Thanks again

    Terry

  104. Well, I came to this article hoping to find a way to stay XHTML 1.0 validated, but open offsite links in a new window (can’t be validated with target in your links) saddly, you can’t be validated with onclick in your links, either… anyone know of any other solutions?

  105. Haven’t tried this way yet. I’m interested in what happens, when you click on this right-way-made popup link with popups banned in your browser (such as Mozilla or some commercial popup-blocking proxies for IE).

    Does it open at least the normal href link?

    In my opinion, popus should not be used, unless necessary, and should be announced in advance (with some icon like for those abroad-targeting links). For example, it’s nice to use popups for internet radios’ “Now playing” windows.

    User just should now that it is a popup.

Got something to say?

We have turned off comments, but you can see what folks had to say before we did so.

More from ALA