/** * jquery.localscroll * copyright (c) 2007-2009 ariel flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com * dual licensed under mit and gpl. * date: 3/11/2009 * * @projectdescription animated scrolling navigation, using anchors. * http://flesler.blogspot.com/2007/10/jquerylocalscroll-10.html * @author ariel flesler * @version 1.2.7 * * @id jquery.fn.localscroll * @param {object} settings hash of settings, it is passed in to jquery.scrollto, none is required. * @return {jquery} returns the same jquery object, for chaining. * * @example $('ul.links').localscroll(); * * @example $('ul.links').localscroll({ filter:'.animated', duration:400, axis:'x' }); * * @example $.localscroll({ target:'#pane', axis:'xy', queue:true, event:'mouseover' }); * * notes: * - the plugin requires jquery.scrollto. * - the hash of settings, is passed to jquery.scrollto, so the settings are valid for that plugin as well. * - jquery.localscroll can be used if the desired links, are all over the document, it accepts the same settings. * - if the setting 'lazy' is set to true, then the binding will still work for later added anchors. * - if onbefore returns false, the event is ignored. **/ ;(function( $ ){ var uri = location.href.replace(/#.*/,''); // local url without hash var $localscroll = $.localscroll = function( settings ){ $('body').localscroll( settings ); }; // many of these defaults, belong to jquery.scrollto, check it's demo for an example of each option. // @see http://flesler.demos.com/jquery/scrollto/ // the defaults are public and can be overriden. $localscroll.defaults = { duration:1000, // how long to animate. axis:'y', // which of top and left should be modified. event:'click', // on which event to react. stop:true, // avoid queuing animations target: window, // what to scroll (selector or element). the whole window by default. reset: true // used by $.localscroll.hash. if true, elements' scroll is resetted before actual scrolling /* lock:false, // ignore events if already animating lazy:false, // if true, links can be added later, and will still work. filter:null, // filter some anchors out of the matched elements. hash: false // if true, the hash of the selected link, will appear on the address bar. */ }; // if the url contains a hash, it will scroll to the pointed element $localscroll.hash = function( settings ){ if( location.hash ){ settings = $.extend( {}, $localscroll.defaults, settings ); settings.hash = false; // can't be true if( settings.reset ){ var d = settings.duration; delete settings.duration; $(settings.target).scrollto( 0, settings ); settings.duration = d; } scroll( 0, location, settings ); } }; $.fn.localscroll = function( settings ){ settings = $.extend( {}, $localscroll.defaults, settings ); return settings.lazy ? // use event delegation, more links can be added later. this.bind( settings.event, function( e ){ // could use closest(), but that would leave out jquery -1.3.x var a = $([e.target, e.target.parentnode]).filter(filter)[0]; // if a valid link was clicked if( a ) scroll( e, a, settings ); // do scroll. }) : // bind concretely, to each matching link this.find('a,area') .filter( filter ).bind( settings.event, function(e){ scroll( e, this, settings ); }).end() .end(); function filter(){// is this a link that points to an anchor and passes a possible filter ? href is checked to avoid a bug in ff. return !!this.href && !!this.hash && this.href.replace(this.hash,'') == uri && (!settings.filter || $(this).is( settings.filter )); }; }; function scroll( e, link, settings ){ var id = link.hash.slice(1), elem = document.getelementbyid(id) || document.getelementsbyname(id)[0]; if ( !elem ) return; if( e ) e.preventdefault(); var $target = $( settings.target ); if( settings.lock && $target.is(':animated') || settings.onbefore && settings.onbefore.call(settings, e, elem, $target) === false ) return; if( settings.stop ) $target.stop(true); // remove all its animations if( settings.hash ){ var attr = elem.id == id ? 'id' : 'name', $a = $(' ').attr(attr, id).css({ position:'absolute', top: $(window).scrolltop(), left: $(window).scrollleft() }); elem[attr] = ''; $('body').prepend($a); location = link.hash; $a.remove(); elem[attr] = id; } $target .scrollto( elem, settings ) // do scroll .trigger('notify.serialscroll',[elem]); // notify serialscroll about this change }; })( jquery );