I have always been interested in elegant yet helpful techniques that in some way extend or rewrite native browser functionality and therefore help making websites a bit more better than they could be. The last time I shared a technique for mobile-friendly and responsive tooltip, which indirectly extends functionality of title attribute in HTML. This time: thoughts and a piece of code for, as titled, more noticeable HTML bookmarks with jQuery.
Actually, it's nothing new, nothing that you could not do or think of on your own. Just sharing thoughts and code of what I have come up with while working on UX purposes.
The Problem
Let's say you have an anchor that links to a particular location (which is actually location of the respective HTML element) on the same or other page of your website. Fine if the element is surrounded with a huge amount of the famous white space, fine if it is in the user-focus area and therefore easily noticeable. But, what if, in the worst case, it is a tiny little object squeezed among larger ones? Actually, I have a pure example here...
There is a small newsletter form in the footer of this website and I would like to encourage you subscribing to my newsletter if you haven't yet. If I bookmarked it in the old way I am pretty sure you would hardly notice the form in a second or two. In web design this is a huge amount of time which means a lot when it comes to engaging users to your product. Fortunately, I think I have an intuitive (yeah, click it) technique for you, so you can design a bit better product.
How It Works
When a page is loaded or an anchor is clicked, the script looks up for an element in HTML by id whose name has been provided via fragment identifier on page-load or href attribute value of an anchor when clicked. If the element exists, the browser then just smoothly scrolls to the location of the element and shakes it horizontally if it has an attribute/value data-bookmark="nudge" defined.
So, it's not only the shake that helps to notice the target, but also, the animated scroll itself makes easier to understand where you are on the page, whether you are being thrown to the top or bottom. I think your users would thank you for that.
Code
Here's a piece of JavaScript code, which is responsible for doing what mentioned above except the nudging.
$( document ).ready( function()
{
function notice( selector )
{
var el = $( selector );
if( el.length < 1 )
return false;
$( 'html, body' ).animate( { scrollTop: el.offset().top }, 500, function()
{
if( el.attr( 'data-bookmark' ) == 'nudge' )
el.nudge();
if( window.location.hash != selector )
window.location.hash = selector;
});
}
$( 'a[href*="#"]' ).click( function( e )
{
var current_url = window.location.toString().replace( /#(.+)/i, '' ).replace(/\/+$/, '' ),
new_url = $( this ).attr( 'href' ).replace( /#(.+)/i, '' ).replace(/\/+$/, '' );
if( new_url == '' || new_url == current_url )
e.preventDefault();
notice( $( this ).attr( 'href' ).replace( /(.+)#/i, '#' ) );
});
if( window.location.hash != '' )
notice( window.location.hash );
});
Now that we have the the first part done, still there is one unknown – a function called nudge. The way I applied it may automatically mean it is a native method of jQuery. Unfortunately not, but why not to extend the library so that we can use this function in a vary of situations later?
No matter how your element is positioned, the function adapts and keeps it in a default state when shake is complete.
jQuery.fn.extend(
{
nudge: function()
{
this.each( function()
{
if( $( this ).is( ':animated' ) )
return false;
var obj = $( this ),
pos = obj.css( 'position' ),
left = obj.css( 'left' ),
left_int = parseInt( left ) || 0;
if( left_int != 0 && left.search( '%' ) > -1 )
left_int = obj.parent().width() * left_int / 100;
if( pos == 'static' )
obj.css( 'position', 'relative' );
setTimeout( function()
{
obj.stop( true, true )
.css( 'left', left_int + 'px' )
.animate( { 'left': left_int - 5 + 'px' }, 50 )
.animate( { 'left': left_int + 10 + 'px' }, 100 )
.animate( { 'left': left_int - 10 + 'px' }, 100 )
.animate( { 'left': left_int + 10 + 'px' }, 100 )
.animate( { 'left': left_int - 10 + 'px' }, 100 )
.animate( { 'left': left_int + 5 + 'px' }, 50, function()
{
obj.css( { 'position': pos, 'left': left } );
});
}, 500 );
});
}
});
Finally, let's just write some typical HTML code, for example:
<a href="#newsletter">Subscribe to newsletter!</a> <!-- here goes some "stranger" code --> <form id="newsletter" data-bookmark="nudge"> <!-- ... --> </form>
I recommend using data-bookmark="nudge" wisely and nudge only what is really necessary. Do not shake huge elements. This may look and feel inadequate and lame.
Info For Dummies or How To Implement
Just put both JavaScript's in existing JS file or create a new one and include in HTML. See the example above and modify your HTML if necessary. That's it, couldn't be more simple.
Post Scriptum
Because I defined nudging function as an extension/method of jQuery, next time I am going to fully justify my behavior by putting it in more use. What about shaking user login form when wrong username/password entered? Yes, that's Apple-inspired.


5 comments. Write?
people who blog about mobile web design should have a site that works on popular devices. please don’t disable zooming until you’re sure your design is bullet proof. I did try to detail what was wrong on my galaxy sii, but the dumb comment widget ate it.
Was going to post that, SII too.
Ok, first I’d like to say that I really, really like your site and work. This is the sort of minimalism that’s only mastered by the pros.
I would like to know if you plan to host the scripts you provide on services like GitHub or such, because the plugins are awesome, but a little difficult to bookmark right now. Also, it would be nice if you provided the assets for the plugins in a zipball, maybe with the demo inside.
Whaddya say?
Keep up the good work pal!
Thanks for you thoughts, Luca. Actually I have recently been thinking about GitHub and files download availability. I will probably give them a go.
Good job. Keep sharing good tutorial.