Accessible Pop-up Links

by Caio Chassot

130 Reader Comments

Back to the Article
  1. 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.

    Copy & paste the code below to embed this comment.
  2. I enjoyed this article because it showed us a nice, clean way to generate a pop-up window without all the nasty “onclick=[removed]…”
    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.

    Copy & paste the code below to embed this comment.
  3. .. 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 :)

    Copy & paste the code below to embed this comment.
  4. 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”

    Copy & paste the code below to embed this comment.
  5. What’s your browser?

    Copy & paste the code below to embed this comment.
  6. 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.

    Copy & paste the code below to embed this comment.
  7. 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 …

    Copy & paste the code below to embed this comment.
  8. 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.

    Copy & paste the code below to embed this comment.
  9. 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!

    Copy & paste the code below to embed this comment.
  10. I haven’t seen anyone else comment on this but Opera 7 loads the link page into both the popup window and the main window – is there a fix?

    Copy & paste the code below to embed this comment.
  11. Works fine here. op 7.23 win2k

    Copy & paste the code below to embed this comment.
  12. 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.

    Copy & paste the code below to embed this comment.
  13. 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.

    Copy & paste the code below to embed this comment.
  14. 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.

    Copy & paste the code below to embed this comment.
  15. Julian, I’m not sure what you mean. In the example page I use mlisten with classes:

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

    Copy & paste the code below to embed this comment.
  16. Hmmm, I will have a go at it again. Your example works, my application of your technique failed – my fault, not yours.

    Copy & paste the code below to embed this comment.
  17. 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.

    Copy & paste the code below to embed this comment.
  18. 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 <a title=”…”>, 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’});

    Copy & paste the code below to embed this comment.
  19. 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;
    }

    Copy & paste the code below to embed this comment.
  20. 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

    Copy & paste the code below to embed this comment.
  21. 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.

    Copy & paste the code below to embed this comment.
  22. 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.

    Copy & paste the code below to embed this comment.
  23. 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.

    Copy & paste the code below to embed this comment.
  24. 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.

    Copy & paste the code below to embed this comment.
  25. Your site looks great! Best of luck to you.

    Copy & paste the code below to embed this comment.
  26. I like the way you set up that your info is the homepage, nicely done. Thanks!

    Copy & paste the code below to embed this comment.
  27. 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?

    Copy & paste the code below to embed this comment.
  28. 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.

    Copy & paste the code below to embed this comment.
  29. In the lasr paragraph:

    Notice that letting this happen DOES NOT result in an accessibility issue since the documents still open (…)

    Copy & paste the code below to embed this comment.
  30. It was a good article, but it havn’t changed my opinion about popups. I will never use them.

    Copy & paste the code below to embed this comment.
  31. >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.

    Copy & paste the code below to embed this comment.
  32. 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.

    Copy & paste the code below to embed this comment.
  33. 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.

    Copy & paste the code below to embed this comment.
  34. 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!

    Copy & paste the code below to embed this comment.
  35. 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)

    Copy & paste the code below to embed this comment.
  36. 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

    Copy & paste the code below to embed this comment.
  37. 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?

    Copy & paste the code below to embed this comment.
  38. 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.

    Copy & paste the code below to embed this comment.
  39. Kali, there’s a solution in the article that works without onclick, and the target attribute is completely optional.

    Copy & paste the code below to embed this comment.
  40. Due to a discussion in a recent post on Simon Willison’s blog (http://simon.incutio.com/archive/2004/05/26/addLoadEvent), I’ve updated “listen” in a more backwards compatible way, that may solve IE5/mac issues. Here’s the new code with a simple event test case: http://v2studio.com/k/code/newlisten.html

    Copy & paste the code below to embed this comment.