Recently a question was posed on StackOverflow.com that sparked my interest. You can head over there to read it yourself. The original poster wanted to know how to make an entire table row (<tr>
) clickable, like a link. This is fairly easy if you’re only after the very redimentary link functionality: it only requires you to register a click handler which will change the location to anything you desire.
An example of this:
$('tr').bind('click', function(){ window.location = 'http://somelocation.com'; // Or, we can grab the HREF from the first anchor: // window.location = $('a:first', this).attr('href'); }); |
This might be deemed suitable by most but, truth be told, it’s an almost pointless enhancement. The same is true for any attempted link simulations. For example, having a DIV element and making it re-locate the page upon a click. Doing this is pointless because it’s not a real link! Browsers offer a bunch of behavioural enhancements to anchors, for example:
- Middle-click: Page opens in new tab.
- CTRL/SHIFT click: Page opens in new window/tab.
- Right-click options: “open in new window”, “copy link location” etc.
- Status message is changed to the HREF of the anchor.
- etc…
It’s impossible to simulate all of the above. Users are left confused and sometimes annoyed when an element doesn’t act like it’s supposed to…
There are no rules that state that table rows or DIV elements cannot be clickable but if you’re going to do so then it’s important to preserve what functionality is expected from anchors. Of course, most users don’t think of them as “anchors”; they’re just links to other pages, but even so, users have a set of unwritten expectations which dictate how websites should behave.
In other words, if you’re going to make an element function like an anchor then it must be an entirely accurate emulation.
So I thought, instead of trying to simulate the expected functionality I could instead simply create an absolutely positioned anchor that moved with the cursor; this anchor would only be activated when the corresponding table row was being hovered. And since it’s a real anchor, all expected functionality is present, including those behavioural enhancement offers by the browser. This is the answer I originally posted on the thread at Stack Overflow.
Then I had another thought; instead of having to update the anchor’s position whenever the document’s mousemove
event triggered, I could just keep it statically hovering over the table row; like a blanket.
I decided to create a jQuery plugin utilizing the above technique:
It works on any element that contains a link. The plugin takes one argument; the selector to target the link within the container, which, by default, is ‘a:first’.
Note: If you plan on binding mouseover
/mouseout
events on the same element that the plugin is running on then make sure to bind both events BEFORE calling the plugin. Also, don’t use mouseenter
/mouseleave
events – the mouseleave
event won’t occur as expected because of the anchor overlay.
Using the plugin is dead simple; say, for example, you have a table with multiple rows; each row has an anchor within the last cell <td>
:
$('table#mytable tr').superLink('a:last'); |
Now every row will seem like one giant anchor to the user!
Thanks for reading! Please share your thoughts with me on Twitter. Have a great day!
That is in deed a really nice idea. But there is one issue that really would bother me if would encounter such an enhanced table. (More then right or shift click capabilities.)
Table data is in most cases data, that shows some interesting numbers, or other data you probably would like to use in other documents. So while hovering an empty a link beneath the mouse cursor, you are not able to select the text to copy it. Maybe you will find a solution for this too.
Cheers,
me
Great plug-in! I’m having a small problem, on slower computers when I move the mouse rapidly across the table, rows remain highlighted even after the mouse is no longer hovering over the row.
Awesome plugin, James. I will definitely be using this in future projects.
You might want to use it on this site as well, for example in p.video, as seen on your jQuery plugin detector post.
I was able to fix my issue by transferring the tr mouseover events to the $targetLink, similar to what you did for the mouseout events. This only shows the active highlight if the computer has time to show the $targetLink, but I think it works better than leaving the lingering highlighted rows. I added the following code:
Very nice and clever solution.
There is already a jQuery plugin that does that, but it doesn’t solve the issues with anchors that u pointed out. Here it is: http://newism.com.au/blog/post/58/bigtarget-js-increasing-the-size-of-clickable-targets/
Cheers.
@Georg, You’re quite right; this definitely is not suitable for all tables, especially those that contain quite a lot of data. For smaller tables with not-so-interesting data this might be useful though. I guess one of the disadvantages in having a
<tr>
behave like an anchor is that it becomes non-selectable (just like anchors)…@Mathias Bynens, great idea; just implemented! 🙂
@Brian, Thank you for the fix Brian; I’ve just added it to the plugin source!
@Jeferson, Unfortunately, like you said, the issues I pointed out are not considered. The plugin you linked to is effectively the same as doing this:
I’ve come across something developing a project, which will be out surely after IE6 dies.
I use lot’s of stuff like:
Unfortunately, this plugin kills the browsers behaviour handled by css 🙁
Any ideas?
Nice plugin
This effeciently kills any CSS-formatting for tr:hover as the previous user says. It also kills formatting for a:hover within the TR’s which is quite a bad thing.
REDO! 🙂