Saturday, April 26, 2008

Retaining Middle-Click Functionality With JavaScript

posted by Jonah Dempcy
Image used under a Creative Commons license. Source

Browsers such as Firefox and Internet Explorer 7 allow users to middle-click on links to open them in a new tab. Oftentimes, JavaScript will be used to add an onclick event to a link that supersedes the link itself. But, when a Firefox or IE7 user middle-clicks the link they may be confronted with any number of sub-par user experiences, such as the new tab containing the same page they were on, or a blank page.

In order to prevent this from happening, a non-JavaScript fallback must be present. Some people only think about the small (estimated less than 5%) amount of users who have JavaScript disabled, and choose not to support those users. That's a conscious decision and I certainly understand it, and condone it as long as there are clearly defined messages to the JS-disabled user that they need to enable JavaScript to use the page.

However, what some people fail to recognize is that even the 95% of users with JavaScript enabled will have sub-par user experiences if there are not non-JS fallbacks cases like this, where middle-clicking a link does nothing but waste the user's time. In order to offer the best user experience and fully utilize the capabilities of the browser, a conscientious JavaScript developer must take a number of measures that might not be apparent at first glance.

When Should Middle-Click Functionality Be Retained?

There are many uses for JavaScript onclick events. Not all of them will need to support the middle click. To determine if it does, ask yourself if it appears as a link to the user. If it looks like a link (be it text, image or button that appears to lead to another page) then it should support middle-click behavior. If it is another use for an onclick event, for instance, a button that clearly performs an action on the current page, then no alternative is necessary.

Take the case of a fancy search results widget that heavily uses JavaScript and Ajax to present search results. Users with JavaScript disabled are presented with instructions on how to enable it, and informed that they won't be able to use the site with out it. So far so good, but unless the search results have a non-JavaScript fallback (unlikely) then middle-clicking them will not have the expected result of some users, which is to take the user to a product detail page.

A real life example: I was interested in tickets to a jazz show and visited the tickets page for that festival. It has a link saying "Watch a video of this artist." I middle-clicked the link, as I usually do, but the next tab contained the exact same information I had just seen-- no video in sight. I inspected the HTML to see that it was a link, but the href was set to "#", in other words, an empty name on the same page.

When I left-clicked the anchor tag, it executed a JavaScript function and opened a popup showing the video. But, middle-clicking proved pointless, as it was a "dummy" anchor tag that should have been a span with cursor: pointer in the CSS.

In fact, I quite commonly see JavaScript onclick events on anchor tags, where the anchor tag serves no other purpose than to make the mouse cursor a pointer. Take the following code, for example:

<a href="#" onclick="showMoreResults();"gt;Show more results</a

If you left-click the link, it will take you to the top of the page (implicit in the "#" name) and execute the showMoreResults() function, which does an Ajax call to fetch more search results, let's say. So far so good. But if you middle-click the link, it will take you to the same page without executing the function. Furthermore, if it's a complex JavaScript application, the state of the application may be lost. In the case of search results, the newly-opened tab may have reset back to the original state of the application, frustrating the user. Of course they can just close the tab and use their existing tab, so all is not lost, but it is still a waste of time from the user's perspective.

If it is truly a JavaScript feature which does not appear as a link, the wise developer would remove the user's ability to middle-click it. By changing it to a span tag, middle-clicking would do nothing.

On the other hand, if it actually looks like a link (and in this case, I think it does), then a middle-click fallback would be nice. Say the user wants to open the next page of search results in the new tab, but stay on the existing page in this tab. Middle-clicking should work, right?

How to Retain Middle-Click Functionality

The way to do this is to set the href attribute of your anchor tags to a page presenting the user with the same content they would get by left-clicking. So, if your app uses Ajax to load in new results by left-clicking, then middle-clicking should take them to the same results on a new page. This is accomplished by setting the href attribute with the correct URL to the content. If you're on search-results.php?page=1 then you would need to set the href to be search-results.php?page=2. The solution varies from app to app but the general idea is to make sure that the href of the link leads to the content advertised in the link.

Next, you need to make sure the onclick event returns false. If you're using inline event registration, it looks like this:

<a href="search-results.php?page=2" onclick="showMoreResults(); return false;">Show more results</a>

This is the same as a non-JavaScript fallback for links. It's a good idea to do this anyway, regardless of middle-click support, as approximately 1-in-20 users will have JS disabled anyway (although this number may vary depending on your particular target market).

Something else to keep in mind is that if you are outputting the href from the server and then showing new results with JavaScript, you'll need to update the href tag as well. Otherwise, you could go to page 1, click "Show more results" and view page 2's results, and then middle-click "Show more results" and be presented with page 2's results again. Why? Because the href was set on page 1 to show page 2's results, and the JavaScript loaded in new results using Ajax. The solution to this is to make sure you update the href to display the correct content each time the application state changes, be it with Ajax or otherwise.

It's fairly straightforward-- if you're on page 10, then when the showMoreResults() function is called you load in new results for page 11 with Ajax, and set the href of the "Show more results" link to point to page 12.

This is just one example using search results, but the same principle applies to any JavaScript actions that the user perceives as links. When middle-clicking the link, or clicking it with JavaScript disabled, the user should be presented with the right content. Otherwise, they will feel like the site is broken, or like they did something wrong. Instead, make sure you've always placed non-JavaScript and middle-click fallbacks in your pages.

Whenever adding an onclick, ask yourself if it looks like a link or a button that would take the user to a new page. Unless the onclick is operating directly on the contents of the current page and it's obvious to the user, consider using the methods outlined above.

Labels: ,

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home