2006-01-31

Bookmarklet tool: Find links to you!

If you are the least bit interested in who links to you and use some service to show you HTTP referrers of site visitors coming to you via inbound links from elsewhere, or see trackbacks from other sites, and so on, you have most likely encoutered this problem, when visiting the page:

Where is that link to me?

I figured I'd make a quick bookmarklet to quickly scroll to the exact spot in a page where the link is, or, if invoked again, to zoom further down the page to the next link, in case there are any.

It turned out quite okay, and as it wasn't much work making it customizable I went that extra bit to make it a tool useful to mostly anybody. Edit: as it eventually turned out, that is just almost true; I took a full hour to polish it up to work better than my original quick and dirty hack. It also illustrates a few good bookmarklet making techniques (more thorough descriptions of a few of these are presented at gazingus.org);

  • Encasing the script in a anonymous function casing so it doesn't leak any variable or funciton names to the page you invoke it on so it won't upset any scripts running at the target page.

  • Creating support functions inside this function casing.

  • Using var to define function local variables.

  • Using the void operator to throw away the return value of a function, so the target page isn't replaced with a document with the value your bookmarklet produced.
I made two variants; the first bookmarklet prompts for a domain name (regexp) to match for all the links in the page, the second matches a fix domain without ever prompting.

Click either of the configure buttons below to set up both scripts to the domain of your preference before bookmarking them. You can click either button again and again to reconfigure the links in the page and bookmark the resulting scripts, if you have a whole slew of sites you want to have bookmarklets for. For the script that prompts for a domain, this sets up the default suggestion, for the other one, it sets which links it will look for.

Regardless of how you configure the scripts, the test will only be performed against the domain name of links, case insensitively (as domain names are not case sensitive) -- if you want to change that, you should be advanced enough to be able to tweak the script to your liking on your own.

Configure scripts by

The first script, which prompts for a domain name regexp:
javascript:void(function()
{
function Y( n )
{
var y = n.offsetTop;
while( n = n.offsetParent )
y += n.offsetTop;
return y
}
var l = document.links, i, u, y, o = [];
if( u = prompt( 'Find links to what domain? (regexp)',
'^ecmanaut\.blogspot\.com$' ) )
{
u = new RegExp( u, 'i' );
for( i = 0; i<l.length; i++ )
if( l[i].host.match( u ) )
o.push( Y(l[i]) );
o.sort( function( a, b ){ return a - b } );
for( i = 0; i<o.length; i++ )
if( (y = o[i]) > pageYOffset )
return scrollTo( 0, y );
alert('No more links found.')
}
})()
The second script, which does not prompt for the domain matcher regexp:
javascript:void(function()
{
function Y( n )
{
var y = n.offsetTop;
while( n = n.offsetParent )
y += n.offsetTop;
return y
}
var l = document.links, i, y, o = [],
u = /^ecmanaut\.blogspot\.com$/i;
for( i = 0; i<l.length; i++ )
if( l[i].host.match( u ) )
o.push( Y(l[i]) );
o.sort( function( a, b ){ return a - b } );
for( i = 0; i<o.length; i++ )
if( (y = o[i]) > pageYOffset )
return scrollTo( 0, y );
alert('No more links found.')
})()
If you want to, you can try clicking either script rather than bookmarking them, to go chasing around this page for links to places so you get a feel for how they work. The default setup prior to customization will look for links staying on this blog.

Things I (re)learned (or remembered a bit late, depending on how you see it) on writing the above scripts:

  • Chasing through document.links processes links in document order (DOM tree order), not to be confused with top-down order of the fully layouted page.

  • Array.prototype.sort() sorts in alphabetical order, which sorts the array [0,3,6,17,4711] as [0,17,3,4711,6] which can be quite different from what you wanted. To sort by numeric values instead, assuming the array only contains numbers, provide a comparison function function( a, b ){ return a-b; } to the sort method.
So those of you who saw the post within the first half hour or so of my posting it, might want to pick up the scripts again. (I opted not to clutter it all down with change markers, to keep the code readable.)

If you use Firefox (or another Mozilla derivate) I recommend editing the bookmarks you save to give each a keyword ("links-to", for instance). That way, you won't have to put it on some panel (or remember where in your maze of bookmarks you put it) to access it when the need arises; just type links-to in the address field and hit return, and the script will be run (and pulled into the address field, should you want to edit it afterwards). This is a very useful technique for keeping lots and lots of tools (not to mention sites) easily accessible, if you like me find it easier to recall names than traversing menu structures. Just hit Ctrl+L, type the script name and hit return. Quick and easy, and even works in full-screen presentation mode when you have no menus or toolbars visible.

This is unfortunately as close to access keys for bookmarks you get in the Mozilla browser family; go vote for bug 47199 now if you too want to put that feature on the development agenda. It has an embarrassing seven votes and was filed in the year 2000, and has not seen much action since. Imagine having any site or handy tool like this a keypress away. You know you want it. So off you go; vote away! Be heard.
blog comments powered by Disqus