daily pastebin goal
4%
SHARE
TWEET

Marcus Mller

a guest Jan 26th, 2009 172 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /**
  2.  * jQuery.serialScroll
  3.  * Copyright (c) 2007-2008 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
  4.  * Dual licensed under MIT and GPL.
  5.  * Date: 3/20/2008
  6.  *
  7.  * @projectDescription Animated scrolling of series.
  8.  * @author Ariel Flesler
  9.  * @version 1.2.1
  10.  *
  11.  * @id jQuery.serialScroll
  12.  * @id jQuery.fn.serialScroll
  13.  * @param {Object} settings Hash of settings, it is passed in to jQuery.ScrollTo, none is required.
  14.  * @return {jQuery} Returns the same jQuery object, for chaining.
  15.  *
  16.  * http://flesler.blogspot.com/2008/02/jqueryserialscroll.html
  17.  *
  18.  * Notes:
  19.  *      - The plugin requires jQuery.ScrollTo.
  20.  *      - The hash of settings, is passed to jQuery.ScrollTo, so its settings can be used as well.
  21.  */
  22. ;(function( $ ){
  23.  
  24.         var $serialScroll = $.serialScroll = function( settings ){
  25.                 $.scrollTo.window().serialScroll( settings );
  26.         };
  27.  
  28.         //Many of these defaults, belong to jQuery.ScrollTo, check it's demo for an example of each option.
  29.         //@see http://flesler.webs/jQuery.ScrollTo/
  30.         $serialScroll.defaults = {//the defaults are public and can be overriden.
  31.                 duration:1000, //how long to animate.
  32.                 axis:'x', //which of top and left should be scrolled
  33.                 event:'click', //on which event to react.
  34.                 start:0, //first element (zero-based index)
  35.                 step:1, //how many elements to scroll on each action
  36.                 lock:true,//ignore events if already animating
  37.                 cycle:true, //cycle endlessly ( constant velocity )
  38.                 constant:true //use contant speed ?
  39.                 /*
  40.                 navigation:null,//if specified, it's a selector a collection of items to navigate the container
  41.                 target:null, //if specified, it's a selector to the element to be scrolled.
  42.                 interval:0, //it's the number of milliseconds to automatically go to the next
  43.                 lazy:false,//go find the elements each time (allows AJAX or JS content, or reordering)
  44.                 stop:false, //stop any previous animations to avoid queueing
  45.                 force:false,//force the scroll to the first element on start ?
  46.                 jump: false,//if true, when the event is triggered on an element, the pane scrolls to it
  47.                 items:null, //selector to the items (relative to the matched elements)
  48.                 prev:null, //selector to the 'prev' button
  49.                 next:null, //selector to the 'next' button
  50.                 onBefore: function(){}, //function called before scrolling, if it returns false, the event is ignored
  51.                 exclude:0 //exclude the last x elements, so we cannot scroll past the end
  52.                 */
  53.         };
  54.  
  55.         $.fn.serialScroll = function( settings ){
  56.                 settings = $.extend( {}, $serialScroll.defaults, settings );
  57.                 var event = settings.event, //this one is just to get shorter code when compressed
  58.                         step = settings.step, // idem
  59.                         lazy = settings.lazy;//idem
  60.  
  61.                 return this.each(function(){
  62.                         var
  63.                                 context = settings.target ? this : document, //if a target is specified, then everything's relative to 'this'.
  64.                                 $pane = $(settings.target || this, context),//the element to be scrolled (will carry all the events)
  65.                                 pane = $pane[0], //will be reused, save it into a variable
  66.                                 items = settings.items, //will hold a lazy list of elements
  67.                                 active = settings.start, //active index
  68.                                 auto = settings.interval, //boolean, do auto or not
  69.                                 nav = settings.navigation, //save it now to make the code shorter
  70.                                 timertype = 'next',
  71.                                 timer; //holds the interval id
  72.  
  73.                         if( !lazy )//if not lazy, go get the items now
  74.                                 items = getItems();
  75.  
  76.                         if( settings.force )
  77.                                 jump( {}, active );//generate an initial call
  78.  
  79.                         // Button binding, optionall
  80.                         $(settings.prev||[], context).bind( event, -step, move );
  81.                         $(settings.next||[], context).bind( event, step, move );
  82.  
  83.                         // Custom events bound to the container
  84.                         if( !pane.ssbound )//don't bind more than once
  85.                                 $pane
  86.                                         .bind('prev.serialScroll', -step, move ) //you can trigger with just 'prev'
  87.                                         .bind('next.serialScroll', step, move ) //for example: $(container).trigger('next');
  88.                                         .bind('goto.serialScroll', jump ); //for example: $(container).trigger('goto', [4] );
  89.                         if( auto )
  90.                                 $pane
  91.                                         .bind('start.serialScroll', function(e){
  92.                                                 if( !auto ){
  93.                                                         clear();
  94.                                                         auto = true;
  95.                                                         timertype = 'next';
  96.                                                         next();
  97.                                                 }
  98.                                          })
  99.                                          .bind('startInverse.serialScroll', function(e){
  100.                                                 if( !auto ){
  101.                                                         clear();
  102.                                                         auto = true;
  103.                                                         timertype = 'prev';
  104.                                                         prev();
  105.                                                 }
  106.                                          })
  107.                                         .bind('stop.serialScroll', function(){//stop a current animation
  108.                                                 clear();
  109.                                                 auto = false;
  110.                                         })
  111.                                         .bind('stopInverse.serialScroll', function(){//stop a current animation
  112.                                                 clear();
  113.                                                 auto = false;
  114.                                         });
  115.                         $pane.bind('notify.serialScroll', function(e, elem){//let serialScroll know that the index changed externally
  116.                                 var i = index(elem);
  117.                                 if( i > -1 )
  118.                                         active = i;
  119.                         });
  120.                         pane.ssbound = true;//avoid many bindings
  121.  
  122.                         if( settings.jump )//can't use jump if using lazy items and a non-bubbling event
  123.                                 (lazy ? $pane : getItems()).bind( event, function( e ){
  124.                                         jump( e, index(e.target) );
  125.                                 });
  126.  
  127.                         if( nav )
  128.                                 nav = $(nav, context).bind(event, function( e ){
  129.                                         e.data = Math.round(getItems().length / nav.length) * nav.index(this);
  130.                                         jump( e, this );
  131.                                 });
  132.  
  133.                         function move( e ){
  134.                                 e.data += active;
  135.                                 jump( e, this );
  136.                         };
  137.                         function jump( e, button ){
  138.                                 if( !isNaN(button) ){//initial or special call from the outside $(container).trigger('goto',[index]);
  139.                                         e.data = button;
  140.                                         button = pane;
  141.                                 }
  142.  
  143.                                 var
  144.                                         pos = e.data, n,
  145.                                         real = e.type, //is a real event triggering ?
  146.                                         $items = settings.exclude ? getItems().slice(0,-settings.exclude) : getItems(),//handle a possible exclude
  147.                                         limit = $items.length,
  148.                                         elem = $items[pos],
  149.                                         duration = settings.duration;
  150.  
  151.                                 if( real )//real event object
  152.                                         e.preventDefault();
  153.  
  154.                                 if( auto ){
  155.                                         clear();//clear any possible automatic scrolling.
  156.                                         if( timertype == 'next') {
  157.                                                 timer = setTimeout( next, settings.interval );
  158.                                         } else if ( timertype == 'prev') {
  159.                                                 timer = setTimeout( prev, settings.interval );
  160.                                         }
  161.                                 }
  162.  
  163.                                 if( !elem ){ //exceeded the limits
  164.                                         n = pos < 0 ? 0 : limit - 1;
  165.                                         if( active != n )//we exceeded for the first time
  166.                                                 pos = n;
  167.                                         else if( !settings.cycle )//this is a bad case
  168.                                                 return;
  169.                                         else
  170.                                                 pos = limit - n - 1;//invert, go to the other side
  171.                                         elem = $items[pos];
  172.                                 }
  173.  
  174.                                 if( !elem || real && active == pos || //could happen, save some CPU cycles in vain
  175.                                         settings.lock && $pane.is(':animated') || //no animations while busy
  176.                                         real && settings.onBefore && //callback returns false ?
  177.                                         settings.onBefore.call(button, e, elem, $pane, getItems(), pos) === false ) return;
  178.  
  179.                                 if( settings.stop )
  180.                                         $pane.queue('fx',[]).stop();//remove all its animations
  181.  
  182.                                 if( settings.constant )
  183.                                         duration = Math.abs(duration/step * (active - pos ));//keep constant velocity
  184.  
  185.                                 $pane
  186.                                         .scrollTo( elem, duration, settings )//do scroll
  187.                                         .trigger('notify.serialScroll',[pos]);//in case serialScroll was called on this elem more than once.
  188.                         };
  189.                         function next(){//I'll use the namespace to avoid conflicts
  190.                                 $pane.trigger('next.serialScroll');
  191.                         };
  192.                         function prev(){//I'll use the namespace to avoid conflicts
  193.                                 $pane.trigger('prev.serialScroll');
  194.                         };
  195.                         function clear(){
  196.                                 clearTimeout(timer);
  197.                         };
  198.                         function getItems(){
  199.                                 return $( items, pane );
  200.                         };
  201.                         function index( elem ){
  202.                                 if( !isNaN(elem) ) return elem;//number
  203.                                 var $items = getItems(), i;
  204.                                 while(( i = $items.index(elem)) == -1 && elem != pane )//see if it matches or one of its ancestors
  205.                                         elem = elem.parentNode;
  206.                                 return i;
  207.                         };
  208.                 });
  209.         };
  210.  
  211. })( jQuery );
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top