Commit 45dcb1b5c4e765fa048492865d2664f52e0a11a9
1 parent
6cec9ed3
Exists in
master
and in
4 other branches
Add jQuery.ScrollTo
Showing
2 changed files
with
226 additions
and
0 deletions
Show diff stats
app/assets/javascripts/application.js
| ... | ... | @@ -0,0 +1,225 @@ |
| 1 | +/** | |
| 2 | + * @depends jquery | |
| 3 | + * @name jquery.scrollto | |
| 4 | + * @package jquery-scrollto {@link http://balupton.com/projects/jquery-scrollto} | |
| 5 | + */ | |
| 6 | + | |
| 7 | +/** | |
| 8 | + * jQuery Aliaser | |
| 9 | + */ | |
| 10 | +(function(window,undefined){ | |
| 11 | + // Prepare | |
| 12 | + var jQuery, $, ScrollTo; | |
| 13 | + jQuery = $ = window.jQuery; | |
| 14 | + | |
| 15 | + /** | |
| 16 | + * jQuery ScrollTo (balupton edition) | |
| 17 | + * @version 1.2.0 | |
| 18 | + * @date July 9, 2012 | |
| 19 | + * @since 0.1.0, August 27, 2010 | |
| 20 | + * @package jquery-scrollto {@link http://balupton.com/projects/jquery-scrollto} | |
| 21 | + * @author Benjamin "balupton" Lupton {@link http://balupton.com} | |
| 22 | + * @copyright (c) 2010 Benjamin Arthur Lupton {@link http://balupton.com} | |
| 23 | + * @license MIT License {@link http://creativecommons.org/licenses/MIT/} | |
| 24 | + */ | |
| 25 | + ScrollTo = $.ScrollTo = $.ScrollTo || { | |
| 26 | + /** | |
| 27 | + * The Default Configuration | |
| 28 | + */ | |
| 29 | + config: { | |
| 30 | + duration: 400, | |
| 31 | + easing: 'swing', | |
| 32 | + callback: undefined, | |
| 33 | + durationMode: 'each', | |
| 34 | + offsetTop: 0, | |
| 35 | + offsetLeft: 0 | |
| 36 | + }, | |
| 37 | + | |
| 38 | + /** | |
| 39 | + * Configure ScrollTo | |
| 40 | + */ | |
| 41 | + configure: function(options){ | |
| 42 | + // Apply Options to Config | |
| 43 | + $.extend(ScrollTo.config, options||{}); | |
| 44 | + | |
| 45 | + // Chain | |
| 46 | + return this; | |
| 47 | + }, | |
| 48 | + | |
| 49 | + /** | |
| 50 | + * Perform the Scroll Animation for the Collections | |
| 51 | + * We use $inline here, so we can determine the actual offset start for each overflow:scroll item | |
| 52 | + * Each collection is for each overflow:scroll item | |
| 53 | + */ | |
| 54 | + scroll: function(collections, config){ | |
| 55 | + // Prepare | |
| 56 | + var collection, $container, container, $target, $inline, position, | |
| 57 | + containerScrollTop, containerScrollLeft, | |
| 58 | + containerScrollTopEnd, containerScrollLeftEnd, | |
| 59 | + startOffsetTop, targetOffsetTop, targetOffsetTopAdjusted, | |
| 60 | + startOffsetLeft, targetOffsetLeft, targetOffsetLeftAdjusted, | |
| 61 | + scrollOptions, | |
| 62 | + callback; | |
| 63 | + | |
| 64 | + // Determine the Scroll | |
| 65 | + collection = collections.pop(); | |
| 66 | + $container = collection.$container; | |
| 67 | + container = $container.get(0); | |
| 68 | + $target = collection.$target; | |
| 69 | + | |
| 70 | + // Prepare the Inline Element of the Container | |
| 71 | + $inline = $('<span/>').css({ | |
| 72 | + 'position': 'absolute', | |
| 73 | + 'top': '0px', | |
| 74 | + 'left': '0px' | |
| 75 | + }); | |
| 76 | + position = $container.css('position'); | |
| 77 | + | |
| 78 | + // Insert the Inline Element of the Container | |
| 79 | + $container.css('position','relative'); | |
| 80 | + $inline.appendTo($container); | |
| 81 | + | |
| 82 | + // Determine the top offset | |
| 83 | + startOffsetTop = $inline.offset().top; | |
| 84 | + targetOffsetTop = $target.offset().top; | |
| 85 | + targetOffsetTopAdjusted = targetOffsetTop - startOffsetTop - parseInt(config.offsetTop,10); | |
| 86 | + | |
| 87 | + // Determine the left offset | |
| 88 | + startOffsetLeft = $inline.offset().left; | |
| 89 | + targetOffsetLeft = $target.offset().left; | |
| 90 | + targetOffsetLeftAdjusted = targetOffsetLeft - startOffsetLeft - parseInt(config.offsetLeft,10); | |
| 91 | + | |
| 92 | + // Determine current scroll positions | |
| 93 | + containerScrollTop = container.scrollTop; | |
| 94 | + containerScrollLeft = container.scrollLeft; | |
| 95 | + | |
| 96 | + // Reset the Inline Element of the Container | |
| 97 | + $inline.remove(); | |
| 98 | + $container.css('position',position); | |
| 99 | + | |
| 100 | + // Prepare the scroll options | |
| 101 | + scrollOptions = {}; | |
| 102 | + | |
| 103 | + // Prepare the callback | |
| 104 | + callback = function(event){ | |
| 105 | + // Check | |
| 106 | + if ( collections.length === 0 ) { | |
| 107 | + // Callback | |
| 108 | + if ( typeof config.callback === 'function' ) { | |
| 109 | + config.callback.apply(this,[event]); | |
| 110 | + } | |
| 111 | + } | |
| 112 | + else { | |
| 113 | + // Recurse | |
| 114 | + ScrollTo.scroll(collections,config); | |
| 115 | + } | |
| 116 | + // Return true | |
| 117 | + return true; | |
| 118 | + }; | |
| 119 | + | |
| 120 | + // Handle if we only want to scroll if we are outside the viewport | |
| 121 | + if ( config.onlyIfOutside ) { | |
| 122 | + // Determine current scroll positions | |
| 123 | + containerScrollTopEnd = containerScrollTop + $container.height(); | |
| 124 | + containerScrollLeftEnd = containerScrollLeft + $container.width(); | |
| 125 | + | |
| 126 | + // Check if we are in the range of the visible area of the container | |
| 127 | + if ( containerScrollTop < targetOffsetTopAdjusted && targetOffsetTopAdjusted < containerScrollTopEnd ) { | |
| 128 | + targetOffsetTopAdjusted = containerScrollTop; | |
| 129 | + } | |
| 130 | + if ( containerScrollLeft < targetOffsetLeftAdjusted && targetOffsetLeftAdjusted < containerScrollLeftEnd ) { | |
| 131 | + targetOffsetLeftAdjusted = containerScrollLeft; | |
| 132 | + } | |
| 133 | + } | |
| 134 | + | |
| 135 | + // Determine the scroll options | |
| 136 | + if ( targetOffsetTopAdjusted !== containerScrollTop ) { | |
| 137 | + scrollOptions.scrollTop = targetOffsetTopAdjusted; | |
| 138 | + } | |
| 139 | + if ( targetOffsetLeftAdjusted !== containerScrollLeft ) { | |
| 140 | + scrollOptions.scrollLeft = targetOffsetLeftAdjusted; | |
| 141 | + } | |
| 142 | + | |
| 143 | + // Perform the scroll | |
| 144 | + if ( $.browser.safari && container === document.body ) { | |
| 145 | + window.scrollTo(scrollOptions.scrollLeft, scrollOptions.scrollTop); | |
| 146 | + callback(); | |
| 147 | + } | |
| 148 | + else if ( scrollOptions.scrollTop || scrollOptions.scrollLeft ) { | |
| 149 | + $container.animate(scrollOptions, config.duration, config.easing, callback); | |
| 150 | + } | |
| 151 | + else { | |
| 152 | + callback(); | |
| 153 | + } | |
| 154 | + | |
| 155 | + // Return true | |
| 156 | + return true; | |
| 157 | + }, | |
| 158 | + | |
| 159 | + /** | |
| 160 | + * ScrollTo the Element using the Options | |
| 161 | + */ | |
| 162 | + fn: function(options){ | |
| 163 | + // Prepare | |
| 164 | + var collections, config, $container, container; | |
| 165 | + collections = []; | |
| 166 | + | |
| 167 | + // Prepare | |
| 168 | + var $target = $(this); | |
| 169 | + if ( $target.length === 0 ) { | |
| 170 | + // Chain | |
| 171 | + return this; | |
| 172 | + } | |
| 173 | + | |
| 174 | + // Handle Options | |
| 175 | + config = $.extend({},ScrollTo.config,options); | |
| 176 | + | |
| 177 | + // Fetch | |
| 178 | + $container = $target.parent(); | |
| 179 | + container = $container.get(0); | |
| 180 | + | |
| 181 | + // Cycle through the containers | |
| 182 | + while ( ($container.length === 1) && (container !== document.body) && (container !== document) ) { | |
| 183 | + // Check Container for scroll differences | |
| 184 | + var scrollTop, scrollLeft; | |
| 185 | + scrollTop = $container.css('overflow-y') !== 'visible' && container.scrollHeight !== container.clientHeight; | |
| 186 | + scrollLeft = $container.css('overflow-x') !== 'visible' && container.scrollWidth !== container.clientWidth; | |
| 187 | + if ( scrollTop || scrollLeft ) { | |
| 188 | + // Push the Collection | |
| 189 | + collections.push({ | |
| 190 | + '$container': $container, | |
| 191 | + '$target': $target | |
| 192 | + }); | |
| 193 | + // Update the Target | |
| 194 | + $target = $container; | |
| 195 | + } | |
| 196 | + // Update the Container | |
| 197 | + $container = $container.parent(); | |
| 198 | + container = $container.get(0); | |
| 199 | + } | |
| 200 | + | |
| 201 | + // Add the final collection | |
| 202 | + collections.push({ | |
| 203 | + '$container': $( | |
| 204 | + ($.browser.msie || $.browser.mozilla) ? 'html' : 'body' | |
| 205 | + ), | |
| 206 | + '$target': $target | |
| 207 | + }); | |
| 208 | + | |
| 209 | + // Adjust the Config | |
| 210 | + if ( config.durationMode === 'all' ) { | |
| 211 | + config.duration /= collections.length; | |
| 212 | + } | |
| 213 | + | |
| 214 | + // Handle | |
| 215 | + ScrollTo.scroll(collections,config); | |
| 216 | + | |
| 217 | + // Chain | |
| 218 | + return this; | |
| 219 | + } | |
| 220 | + }; | |
| 221 | + | |
| 222 | + // Apply our jQuery Prototype Function | |
| 223 | + $.fn.ScrollTo = $.ScrollTo.fn; | |
| 224 | + | |
| 225 | +})(window); | ... | ... |