Ultimate NYTimes jQuery Slidebox
The New York Times has a pretty fancy box that slides out when you hit the bottom of an article. It draws attention without being too distracting. Very nice. Here’s how you can do it yourself with all the trendiest bells and whistles, CSS animation (with backup jQuery for crippled browsers), and google analytics tracking. See it in the wild over at my other blog TwoShay, or jump straight to the demo to grab the code.
To start with, some basic skeleton code. I’m using new HTML5 selectors, you can just use divs if you’re not that cool.
1 2 3 4 5 6 7 8 9 10 11 |
<section id='slidebox'> <a name='close'></a> <h1>Related Reading</h1> <div class='related'> <h2>Sense and Sensibility</h2> <p class='desc'> Another book by Jane Austen you will enjoy <a href='#' rel='related' class='more'>Read »</a> </p> </div> </section> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
/* Just the important styles - see the demo source for a fuller account */ #slidebox { position:fixed; width:400px; right: -430px; bottom:20px; -webkit-transition: right 100ms linear; } #slidebox.open { right: 0px; -webkit-transition: right 300ms linear; } |
This sets up an absolutely positioned box, hidden off to the right of screen. Adding a class of open to the box using jQuery will trigger a 300ms CSS animation to slide the box in, nice and smooth. The correct time to do this is when the user scrolls to the last bit of content on the page. What this content is will be dependent on your site, but whatever it is flag it with an id of #last. The following javascript is all we need:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
(function ($) { /* Add a function to jQuery to slidebox any elements */ jQuery.fn.slidebox = function() { var slidebox = this; var originalPosition = slidebox.css('right'); var boxAnimations = { open: function() { slidebox.addClass('open'); }, close: function() { slidebox.removeClass('open'); }, } $(window).scroll(function() { var distanceTop = $('#last').offset().top - $(window).height(); if ($(window).scrollTop() > distanceTop) { boxAnimations.open(); } else { boxAnimations.close(); } }); } $(function() { /* onload */ $('#slidebox').slidebox(); }); }); |
That’s it! Everything from here on is gravy.
To deal with browsers that don’t support CSS animations yet, provide a fallback that uses jQuery animation using Modernizr to detect the browser’s capabilities:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
/* replacing the boxAnimations definition above */ var boxAnimations; if (Modernizr.cssanimations) { boxAnimations = { open: function() { slidebox.addClass('open'); }, close: function() { slidebox.removeClass('open'); }, } } else { boxAnimations = { open: function() { slidebox.animate({ 'right': '0px' }, 300); }, close: function() { slidebox.stop(true).animate({ 'right': originalPosition }, 100); } } } |
A close button is polite, allowing the user to dismiss the slidebox if they are not interested:
1 2 3 |
slidebox.find('.close').click(function() { $(this).parent().remove(); }); |
And finally, no point adding all this shiny without knowing whether people are using it! Google analytics allows us to track custom javascript events, which is a perfect tool for gaining an insight into how the slidebox is performing. It’s easy to use: simply push a _trackEvent method call to the _gaq variable (defined in the analytics snippet you copy and paste into your layout) and google takes care of the rest. Observe the full javascript code, with tracking added:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
(function ($) { jQuery.fn.slidebox = function() { var slidebox = this; var originalPosition = slidebox.css('right'); var open = false; /* GA tracking */ var track = function(label) { return _gaq.push(['_trackEvent', 'Slidebox', label]); } var boxAnimations; if (Modernizr.cssanimations) { boxAnimations = { open: function() { slidebox.addClass('open'); }, close: function() { slidebox.removeClass('open'); }, } } else { boxAnimations = { open: function() { slidebox.animate({ 'right': '0px' }, 300); }, close: function() { slidebox.stop(true).animate({ 'right': originalPosition }, 100); } } } $(window).scroll(function() { var distanceTop = $('#last').offset().top - $(window).height(); if ($(window).scrollTop() > distanceTop) { /* Extra protection necessary so we don't send multiple open events to GA */ if (!open) { open = true; boxAnimations.open(); track("Open"); } } else { open = false; boxAnimations.close(); } }); slidebox.find('.close').click(function() { $(this).parent().remove(); track("Close"); }); slidebox.find('.related a').click(function() { track("Read More"); }); } $(function() { $('#slidebox').slidebox(); }); })(jQuery); /* Google analytics code provides this variable */ var _gaq = _gaq || []; |
Tasty. For the entire code and complete styles, see the demo page.
Kudos to http://tympanus.net for getting the ball rolling.
July 02, 2010 at 11:52 AM
This is really great! I am glad that you could use our little script as inspiration! Cheers, Mary Lou
September 21, 2010 at 10:11 PM
Very nice. I'm seeing some rendering issues in Opera (ver. 10.62). Sometimes the box doesn't slide out, other times it's only partially visible. Could this be caused by a problem with the browser determining (incorrectly) the height?
February 08, 2011 at 7:28 PM
I love this slider... how would I go about adding it to a Wordpress based sight?
February 15, 2011 at 9:52 AM
George: Sorry I don't support Opera, not sure what the issue is.
Dennis: Perhaps this plugin?
July 01, 2011 at 11:22 PM
Using a separate CSS stylesheet, I have troubles with getting this code to work. do you have any ideas? should i make any changes to the code?
July 02, 2011 at 10:16 AM
issue settled. it had nothing to do with separate css. GREAT CODE, Thanks a lot!
October 31, 2011 at 12:13 PM
Hello there and thanks for the great tutorial!
i'm using the code provited at tympanus.net for the slide in box and everything is working fine!
what i want to add is the ga tracking code, but i'm not sure what i should add...
could u please help me.. ?
should i include the new ga code
http://code.google.com/intl/el-GR/apis/analytics/docs/tracking/asyncTracking.html
and just add the following to the my js file ?
/* GA tracking */ var track = function(label) { return _gaq.push(['_trackEvent', 'my_css_id_for_the_slider', label]); }it that all? or i should also configure something in the analytics settings?
thx
fotis