]> git.ipfire.org Git - people/shoehn/ipfire.org.git/blame - static/js/jquery-scrollto.js
Feature page complete page markup and added new icons
[people/shoehn/ipfire.org.git] / static / js / jquery-scrollto.js
CommitLineData
3c77f292
SH
1/***
2umd: true
3***/
4
5(function () {
6 // Prepare
7 var $, ScrollTo
8 $ = window.jQuery || require('jquery')
9
10 // Fix scrolling animations on html/body on safari
11 $.propHooks.scrollTop = $.propHooks.scrollLeft = {
12 get: function (elem, prop) {
13 var result = null
14 if ( elem.tagName === 'HTML' || elem.tagName === 'BODY' ) {
15 if ( prop === 'scrollLeft' ) {
16 result = window.scrollX
17 }
18 else if ( prop === 'scrollTop' ) {
19 result = window.scrollY
20 }
21 }
22 if ( result == null ) {
23 result = elem[prop]
24 }
25 return result
26 }
27 }
28 $.Tween.propHooks.scrollTop = $.Tween.propHooks.scrollLeft = {
29 get: function (tween) {
30 return $.propHooks.scrollTop.get(tween.elem, tween.prop)
31 },
32 set: function (tween) {
33 // Our safari fix
34 if ( tween.elem.tagName === 'HTML' || tween.elem.tagName === 'BODY' ) {
35 // Defaults
36 tween.options.bodyScrollLeft = (tween.options.bodyScrollLeft || window.scrollX)
37 tween.options.bodyScrollTop = (tween.options.bodyScrollTop || window.scrollY)
38
39 // Apply
40 if ( tween.prop === 'scrollLeft' ) {
41 tween.options.bodyScrollLeft = Math.round(tween.now)
42 }
43 else if ( tween.prop === 'scrollTop' ) {
44 tween.options.bodyScrollTop = Math.round(tween.now)
45 }
46
47 // Apply
48 window.scrollTo(tween.options.bodyScrollLeft, tween.options.bodyScrollTop)
49 }
50 // jQuery's IE8 Fix
51 else if ( tween.elem.nodeType && tween.elem.parentNode ) {
52 tween.elem[tween.prop] = tween.now
53 }
54 }
55 }
56
57 // jQuery ScrollTo
58 ScrollTo = {
59 // Configuration
60 config: {
61 duration: 400,
62 easing: 'swing',
63 callback: null,
64 durationMode: 'each',
65 offsetTop: 0,
66 offsetLeft: 0
67 },
68
69 // Set Configuration
70 configure: function (options) {
71 // Apply Options to Config
72 $.extend(ScrollTo.config, options || {})
73
74 // Chain
75 return this
76 },
77
78 // Perform the Scroll Animation for the Collections
79 // We use $inline here, so we can determine the actual offset start for each overflow:scroll item
80 // Each collection is for each overflow:scroll item
81 scroll: function (collections, config) {
82 // Prepare
83 var collection, $container, $target, $inline, position,
84 containerScrollTop, containerScrollLeft,
85 containerScrollTopEnd, containerScrollLeftEnd,
86 startOffsetTop, targetOffsetTop, targetOffsetTopAdjusted,
87 startOffsetLeft, targetOffsetLeft, targetOffsetLeftAdjusted,
88 scrollOptions,
89 callback
90
91 // Determine the Scroll
92 collection = collections.pop()
93 $container = collection.$container
94 $target = collection.$target
95
96 // Prepare the Inline Element of the Container
97 $inline = $('<span/>').css({
98 'position': 'absolute',
99 'top': '0px',
100 'left': '0px'
101 })
102 position = $container.css('position')
103
104 // Insert the Inline Element of the Container
105 $container.css({position: 'relative'})
106 $inline.appendTo($container)
107
108 // Determine the top offset
109 startOffsetTop = $inline.offset().top
110 targetOffsetTop = $target.offset().top
111 targetOffsetTopAdjusted = targetOffsetTop - startOffsetTop - parseInt(config.offsetTop, 10)
112
113 // Determine the left offset
114 startOffsetLeft = $inline.offset().left
115 targetOffsetLeft = $target.offset().left
116 targetOffsetLeftAdjusted = targetOffsetLeft - startOffsetLeft - parseInt(config.offsetLeft, 10)
117
118 // Determine current scroll positions
119 containerScrollTop = $container.prop('scrollTop')
120 containerScrollLeft = $container.prop('scrollLeft')
121
122 // Reset the Inline Element of the Container
123 $inline.remove()
124 $container.css({position: position})
125
126 // Prepare the scroll options
127 scrollOptions = {}
128
129 // Prepare the callback
130 callback = function () {
131 // Check
132 if ( collections.length === 0 ) {
133 // Callback
134 if ( typeof config.callback === 'function' ) {
135 config.callback()
136 }
137 }
138 else {
139 // Recurse
140 ScrollTo.scroll(collections, config)
141 }
142 // Return true
143 return true
144 }
145
146 // Handle if we only want to scroll if we are outside the viewport
147 if ( config.onlyIfOutside ) {
148 // Determine current scroll positions
149 containerScrollTopEnd = containerScrollTop + $container.height()
150 containerScrollLeftEnd = containerScrollLeft + $container.width()
151
152 // Check if we are in the range of the visible area of the container
153 if ( containerScrollTop < targetOffsetTopAdjusted && targetOffsetTopAdjusted < containerScrollTopEnd ) {
154 targetOffsetTopAdjusted = containerScrollTop
155 }
156 if ( containerScrollLeft < targetOffsetLeftAdjusted && targetOffsetLeftAdjusted < containerScrollLeftEnd ) {
157 targetOffsetLeftAdjusted = containerScrollLeft
158 }
159 }
160
161 // Determine the scroll options
162 if ( targetOffsetTopAdjusted !== containerScrollTop ) {
163 scrollOptions.scrollTop = targetOffsetTopAdjusted
164 }
165 if ( targetOffsetLeftAdjusted !== containerScrollLeft ) {
166 scrollOptions.scrollLeft = targetOffsetLeftAdjusted
167 }
168
169 // Check to see if the scroll is necessary
170 if ( $container.prop('scrollHeight') === $container.height() ) {
171 delete scrollOptions.scrollTop
172 }
173 if ( $container.prop('scrollWidth') === $container.width() ) {
174 delete scrollOptions.scrollLeft
175 }
176
177 // Perform the scroll
178 if ( scrollOptions.scrollTop != null || scrollOptions.scrollLeft != null ) {
179 $container.animate(scrollOptions, {
180 duration: config.duration,
181 easing: config.easing,
182 complete: callback
183 })
184 }
185 else {
186 callback()
187 }
188
189 // Return true
190 return true
191 },
192
193 // ScrollTo the Element using the Options
194 fn: function (options) {
195 // Prepare
196 var collections, config, $container, container
197 collections = []
198
199 // Prepare
200 var $target = $(this)
201 if ( $target.length === 0 ) {
202 // Chain
203 return this
204 }
205
206 // Handle Options
207 config = $.extend({}, ScrollTo.config, options)
208
209 // Fetch
210 $container = $target.parent()
211 container = $container.get(0)
212
213 // Cycle through the containers
214 while ( ($container.length === 1) && (container !== document.body) && (container !== document) ) {
215 // Check Container for scroll differences
216 var containerScrollTop, containerScrollLeft
217 containerScrollTop = $container.css('overflow-y') !== 'visible' && container.scrollHeight !== container.clientHeight
218 containerScrollLeft = $container.css('overflow-x') !== 'visible' && container.scrollWidth !== container.clientWidth
219 if ( containerScrollTop || containerScrollLeft ) {
220 // Push the Collection
221 collections.push({
222 '$container': $container,
223 '$target': $target
224 })
225 // Update the Target
226 $target = $container
227 }
228 // Update the Container
229 $container = $container.parent()
230 container = $container.get(0)
231 }
232
233 // Add the final collection
234 collections.push({
235 '$container': $('html'),
236 // document.body doesn't work in firefox, html works for all
237 // internet explorer starts at the beggining
238 '$target': $target
239 })
240
241 // Adjust the Config
242 if ( config.durationMode === 'all' ) {
243 config.duration /= collections.length
244 }
245
246 // Handle
247 ScrollTo.scroll(collections, config)
248
249 // Chain
250 return this
251 }
252 }
253
254 // Apply our extensions to jQuery
255 $.ScrollTo = $.ScrollTo || ScrollTo
256 $.fn.ScrollTo = $.fn.ScrollTo || ScrollTo.fn
257
258 // Export
259 return ScrollTo
260}).call(this)