Archive for October, 2008

(Another) Scrollable Plugin for jQuery

I was having a bit of difficulty finding a jQuery plugin that not only provided scrolling behavior to a list of elements, but also used & then generated markup that could still be accessible, semantic & validate whether or not the user ran the javascript.

jQueryThe best plugin that I could find that was already out there was Tero Piirainen's jquery.scrollable.js. If you check it out you'll quickly see that the markup that's used to generate the scrolling items could be improved upon. Nothing in my version of jquery.scrollable.js removes functionality from what Tero put together, and the improvements are basic.

  1. make those items scrollable horizotally or vertically
  2. decide how many items are visible at once
  3. scroll elements with mouse, arrow keys and mousewheel (requires mousewheel.js)
  4. make navigational buttons without programming
  5. have programmatic actions: next, prev, nextPage, prevPage, seekTo, begin, end
  6. need to know when list is scrolled with custom event listener
  7. You can now start with semantic markup
  8. I want this all in single js file that weights only 3.9 4.1 Kb minified!

First we start with simple & semantic markup

There's nothing fancy going on here at all, just a wrapping element, an anchor and an unordered list. Unfortunately due to the design requirements of this particular implementation, an additional <div> had to be added. If it wasn't for the creative constraint, and the lack of support for vertical-align: middle across many browsers, this extra <div> would have not been included.

HTML:
  1. <div class="scrolling-list">
  2.     <a href="#newspage" class="more-link">More News</a>
  3.   <ol>
  4.         <li><div><a href="#">Someone reports second-quarter 2008 earnings &raquo;</a></div></li>
  5.         <li><div><a href="#">Bear scares comedian, everybody laughs &raquo;</a></div></li>
  6.         <li><div><a href="#">Someone Completes Someone else's Acquisition &raquo;</a></div></li>
  7.         <li><div><a href="#">Someone selected by Some Company, S.A.B. de C.V. for ADR program &raquo;</a></div></li>
  8.         <li><div><a href="#">Someone wins landmark multinational asset pooling mandate &raquo;</a></div></li>
  9.         <li><div><a href="#">Someone Announces Internal Restructuring Transactions and Guarantees Related to Acquisition &raquo;</a></div></li>
  10.         <li><div><a href="#">Someone wins comprehensive custodial mandate with one of New Zealand's largest organizations &raquo;</a></div></li>
  11.         <li><div><a href="#">Someone selected by East Timor to provide custodial services and training opportunities &raquo;</a></div></li>
  12.         <li><div><a href="#">Someone launches latest Global Derivatives Collateral offering &raquo;</a></div></li>
  13.         <li><div><a href="#">Someone expands Boston fund services operations &raquo;</a></div></li>
  14.   </ol>
  15. </div>

Presentation

Now we add styling that makes it match the look & feel of the main site.

The css required to make this bit work for you will be different for every project, so take a look at the included styles and tweak as necessary.

And now for the behavior

If the user's browser allows javascript to run, we add some additional unobtrusive behavior (including mousewheel support)

JavaScript:
  1. jQuery(function( $ ){
  2.     /**
  3.      * make sure the CSS knows that we're modifying the DOM and then style accordingly
  4.      **/       
  5.     $('.scrollable').addClass('js');
  6.     /**
  7.      * If you have an element you'd like to use the same style, but not attach the
  8.      * behavior you can turn it off by first adding the scrollable classname, but making
  9.      * sure the js classname is not applied to the element (this is what I did to show the
  10.      * "no javascript" version in the second example). Keeping the use of the scrollable
  11.      * classname for the general styles prevents having to write redundant styles
  12.      **/
  13.     $('.scrollable.nojs').removeClass('js');
  14.     /**
  15.      * a little DOM modification to keep all of the markup valid
  16.      **/
  17.     $('.scrollable.js ol').attr('id','items').wrap('<ul><li></li></ul>');
  18.     $('.scrollable.js ul>li').attr('id','itemswrapper');
  19.     var emptyLinkTarget = (window.opera) ? "#" : "javascript:function(){return}"; // a hash breaks a few flavors of IE & a javascript link (though it's poor form) breaks Opera.
  20.     $('.scrollable.js ul').prepend('<li><a class="prev" href="'+emptyLinkTarget+'">&lt;&lt;</a></li>').append('<li><a class="next" href="'+emptyLinkTarget+'">&gt;&gt;</a></li>');
  21.     /**
  22.      * and now we initiate
  23.      **/
  24.     $('.scrollable.js').scrollable({
  25.         size:3,
  26.         horizontal:false,
  27.         duration:1500,
  28.         items:'#items',
  29.         prev:'.prev',
  30.         next:'.next'
  31.     });
  32. });

This is the generated source we end up with... There's one thing you might notice, and that's the div class="__scrollable", though I initially placed that element outside of it's parent ol it did not work. It has something to do with how the xhtml 1.0 strict doctype is handled by the browsers. Though this may work in HTML 4.0 or various browser quirks modes, I haven't specifically tested all possible cases.

HTML:
  1. <div class="scrollable js">
  2.     <a href="#" class="more-link">More News</a>
  3.     <ul>
  4.         <li><a class="prev" href="javascript:function(){return}">&lt;&lt;</a></li>
  5.         <li id="itemswrapper">
  6.             <ol style="overflow: hidden; position: relative; visibility: visible; height: 124px;" id="items">
  7.                 <div class="__scrollable" style="position: absolute; height: 200000em;">
  8.                     <li><div><a href="#">Someone reports second-quarter 2008 earnings »</a></div></li>
  9.                     <li><div><a href="#">Bear scares comedian, everybody laughs »</a></div></li>
  10.                     <li><div><a href="#">Someone Completes Someone else's Acquisition »</a></div></li>
  11.                     <li><div><a href="#">Someone selected by Some Company, S.A.B. de C.V. for ADR program »</a></div></li>
  12.                     <li><div><a href="#">Someone wins landmark multinational asset pooling mandate »</a></div></li>
  13.                     <li><div><a href="#">Someone Announces Internal Restructuring Transactions and Guarantees Related to Acquisition »</a></div></li>
  14.                     <li><div><a href="#">Someone wins comprehensive custodial mandate with one of New Zealand's largest organizations »</a></div></li>
  15.                     <li><div><a href="#">Someone selected by East Timor to provide custodial services and training opportunities »</a></div></li>
  16.                     <li><div><a href="#">Someone launches latest Global Derivatives Collateral offering »</a></div></li>
  17.                     <li><div><a href="#">Someone expands Boston fund services operations »</a></div></li>
  18.                 </div>
  19.                 <br clear="all"/>
  20.             </ol>
  21.         </li>
  22.         <li><a class="next" href="javascript:function(){return}">&gt;&gt;</a></li>
  23.     </ul>
  24. </div>

This build is currently in a non-public svn repository, but I will be moving it to google code or github shortly (depending on whether or not I feel like learning how to use Git)

Standalone Demo:
http://www.naterkane.com/sandbox/scrollable/
Download:
First you'll of course need jQuery v.1.2.6
jquery.scrollable.js (7.5k)
jquery.scrollable.min.js (4.1k)
scrolling-list.css – the stylesheet used for the example
You can also grab a copy of jquery.mousewheel.js here


new NK&F logo

new NK&F logo
new NK&F logo, originally uploaded by naterkane.

it was time to update the very bogus & bad mark that we've been using for Nater Kane & Friends. comments are of course welcome.

Similar Posts

Categories

Archives

About

Nater Kane is freelance developer and user experience & technology consultant based in Brooklyn, NY.

Nater's focus is on creating a semantic and accessible web, and having delighted clients with happy customers.

He likes to spend time playing with his cats, playing drums, working on his diesel vw rabbit and his motorcycle, and enjoying a decent espresso.

RSS

Twitter » What I'm Up To

  • I wish the bank wasn't a 3/4 mi walk in the rain. Yuck 39 mins ago
  • just found out last night that 1/2 of my today is booked interviewing some folks... need to bring some more people on board at @wearenom 1 hr ago
  • time to head down the street to the bank, emergency check-bounce prevention deposit only because this simple chore has escaped me for days. 1 hr ago
  • More updates...

How I'm Social

Basecamp

Meta


Nater Kane naterkane personal http://www.naterkane.com LinkedIn Profile Web Technologist personal nater@naterkane.com 1978-09-12 voice 845.234.6698 | fax 707.922.0593
964 Flushing Ave. Brooklyn, NY 11206