PageSourceSearch

https://gatchinapalace.ru/sourse/cusel/js/jScrollPane.js

js gatchinapalace.ru collected 2026-10-02 10:49:33 UTC 15,119 bytes, 472 lines download raw bytes

1(function($) {
2
3$.jScrollPaneCusel = {
4	active : []
5};
6$.fn.jScrollPaneCusel = function(settings)
7{
8	settings = $.extend({}, $.fn.jScrollPaneCusel.defaults, settings);
9
10	var rf = function() { return false; };
11	
12	return this.each(
13		function()
14		{
15			var $this = $(this);
16			var cuselWid = this.parentNode.offsetWidth;
17			
18						
19			// Switch the element's overflow to hidden to ensure we get the size of the element without the scrollbars [http://plugins.jquery.com/node/1208]
20			$this.css('overflow', 'hidden');
21			var paneEle = this;
22			if ($(this).parent().is('.jScrollPaneContainer')) {
23				var currentScrollPosition = settings.maintainPosition ? $this.position().top : 0;
24				var $c = $(this).parent();
25				var paneWidth = cuselWid;
26				var paneHeight = $c.outerHeight();
27				var trackHeight = paneHeight;
28				$('>.jScrollPaneTrack, >.jScrollArrowUp, >.jScrollArrowDown', $c).remove();
29				$this.css({'top':0});
30			} else {
31				var currentScrollPosition = 0;
32				this.originalPadding = $this.css('paddingTop') + ' ' + $this.css('paddingRight') + ' ' + $this.css('paddingBottom') + ' ' + $this.css('paddingLeft');
33				this.originalSidePaddingTotal = (parseInt($this.css('paddingLeft')) || 0) + (parseInt($this.css('paddingRight')) || 0);
34				
35				
36				var paneWidth = cuselWid;
37				var paneHeight = $this.innerHeight();
38				var trackHeight = paneHeight;
39				$this
40					.wrap("<div class='jScrollPaneContainer'></div>")
41					.parent().css({'height':paneHeight+'px', 'width':paneWidth+'px'});
42				if(!window.navigator.userProfile) /* for ie6 ne umenshaem width block na tolshinu bordera */
43				{
44					var borderWid = parseInt($(this).parent().css("border-left-width"))+parseInt($(this).parent().css("border-right-width"));
45					paneWidth-=borderWid;
46					$(this)
47						.css("width",paneWidth+"px")
48						.parent().css("width",paneWidth+"px");
49				
50				}
51				// deal with text size changes (if the jquery.em plugin is included)
52				// and re-initialise the scrollPane so the track maintains the
53				// correct size
54				$(document).bind(
55					'emchange', 
56					function(e, cur, prev)
57					{
58						$this.jScrollPaneCusel(settings);
59					}
60				);
61				
62			}
63			
64			
65			if (settings.reinitialiseOnImageLoad) {
66				// code inspired by jquery.onImagesLoad: http://plugins.jquery.com/project/onImagesLoad
67				// except we re-initialise the scroll pane when each image loads so that the scroll pane is always up to size...
68				// TODO: Do I even need to store it in $.data? Is a local variable here the same since I don't pass the reinitialiseOnImageLoad when I re-initialise?
69				var $imagesToLoad = $.data(paneEle, 'jScrollPaneImagesToLoad') || $('img', $this);
70				var loadedImages = [];
71				
72				if ($imagesToLoad.length) {
73					$imagesToLoad.each(function(i, val)	{
74						$(this).bind('load', function() {
75							if($.inArray(i, loadedImages) == -1){ //don't double count images
76								loadedImages.push(val); //keep a record of images we've seen
77								$imagesToLoad = $.grep($imagesToLoad, function(n, i) {
78									return n != val;
79								});
80								$.data(paneEle, 'jScrollPaneImagesToLoad', $imagesToLoad);
81								settings.reinitialiseOnImageLoad = false;
82								$this.jScrollPaneCusel(settings); // re-initialise
83							}
84						}).each(function(i, val) {
85							if(this.complete || this.complete===undefined) { 
86								//needed for potential cached images
87								this.src = this.src; 
88							} 
89						});
90					});
91				};
92			}
93
94			var p = this.originalSidePaddingTotal;
95			
96			var cssToApply = {
97				'height':'auto',
98				'width':paneWidth - settings.scrollbarWidth - settings.scrollbarMargin - p + 'px'
99			}
100
101			if(settings.scrollbarOnLeft) {
102				cssToApply.paddingLeft = settings.scrollbarMargin + settings.scrollbarWidth + 'px';
103			} else {
104				cssToApply.paddingRight = settings.scrollbarMargin + 'px';
105			}
106
107			$this.css(cssToApply);
108
109			var contentHeight = $this.outerHeight();
110			var percentInView = paneHeight / contentHeight;
111
112			if (percentInView < .99) {
113				var $container = $this.parent();
114				
115				$container.append(
116					$('<div class="jScrollPaneTrack"></div>').css({'width':settings.scrollbarWidth+'px'}).append(
117						$('<div class="jScrollPaneDrag"></div>').css({'width':settings.scrollbarWidth+'px'}).append(
118							$('<div class="jScrollPaneDragTop"></div>').css({'width':settings.scrollbarWidth+'px'}),
119							$('<div class="jScrollPaneDragBottom"></div>').css({'width':settings.scrollbarWidth+'px'})
120						)
121					)
122				);
123				
124				var $track = $('>.jScrollPaneTrack', $container);
125				var $drag = $('>.jScrollPaneTrack .jScrollPaneDrag', $container);
126								
127				
128				if (settings.showArrows) {
129					
130					var currentArrowButton;
131					var currentArrowDirection;
132					var currentArrowInterval;
133					var currentArrowInc;
134					var whileArrowButtonDown = function()
135					{
136						if (currentArrowInc > 4 || currentArrowInc%4==0) {
137							positionDrag(dragPosition + currentArrowDirection * mouseWheelMultiplier);
138						}
139						currentArrowInc ++;
140					};
141					var onArrowMouseUp = function(event)
142					{
143						$('html').unbind('mouseup', onArrowMouseUp);
144						currentArrowButton.removeClass('jScrollActiveArrowButton');
145						clearInterval(currentArrowInterval);
146					};
147					var onArrowMouseDown = function() {
148						$('html').bind('mouseup', onArrowMouseUp);
149						currentArrowButton.addClass('jScrollActiveArrowButton');
150						currentArrowInc = 0;
151						whileArrowButtonDown();
152						currentArrowInterval = setInterval(whileArrowButtonDown, 100);
153					};
154					$container
155						.append(
156							$('<div></div>')
157								.attr({'class':'jScrollArrowUp'})
158								.css({'width':settings.scrollbarWidth+'px'})
159								.bind('mousedown', function()
160								{
161									currentArrowButton = $(this);
162									currentArrowDirection = -1;
163									onArrowMouseDown();
164									this.blur();
165									return false;
166								})
167								.bind('click', rf),
168							$('<div></div>')
169								.attr({'class':'jScrollArrowDown'})
170								.css({'width':settings.scrollbarWidth+'px'})
171								.bind('mousedown', function()
172								{
173									currentArrowButton = $(this);
174									currentArrowDirection = 1;
175									onArrowMouseDown();
176									this.blur();
177									return false;
178								})
179								.bind('click', rf)
180						);
181					var $upArrow = $('>.jScrollArrowUp', $container);
182					var $downArrow = $('>.jScrollArrowDown', $container);
183					if (settings.arrowSize) {
184						trackHeight = paneHeight - settings.arrowSize - settings.arrowSize;
185						$track
186							.css({'height': trackHeight+'px', top:settings.arrowSize+'px'})
187					} else {
188						var topArrowHeight = $upArrow.height();
189						settings.arrowSize = topArrowHeight;
190						trackHeight = paneHeight - topArrowHeight - $downArrow.height();
191						$track
192							.css({'height': trackHeight+'px', top:topArrowHeight+'px'})
193					}
194				}
195				
196				var $pane = $(this).css({'position':'absolute', 'overflow':'visible'});
197				
198				var currentOffset;
199				var maxY;
200				var mouseWheelMultiplier;
201				// store this in a seperate variable so we can keep track more accurately than just updating the css property..
202				var dragPosition = 0;
203				var dragMiddle = percentInView*paneHeight/2;
204				
205				// pos function borrowed from tooltip plugin and adapted...
206				var getPos = function (event, c) {
207					var p = c == 'X' ? 'Left' : 'Top';
208					return event['page' + c] || (event['client' + c] + (document.documentElement['scroll' + p] || document.body['scroll' + p]
208)) || 0;
209				};
210				
211				var ignoreNativeDrag = function() {	return false; };
212				
213				var initDrag = function()
214				{
215					ceaseAnimation();
216					currentOffset = $drag.offset(false);
217					currentOffset.top -= dragPosition;
218					maxY = trackHeight - $drag[0].offsetHeight;
219					mouseWheelMultiplier = 2 * settings.wheelSpeed * maxY / contentHeight;
220				};
221				
222				var onStartDrag = function(event)
223				{
224					initDrag();
225					dragMiddle = getPos(event, 'Y') - dragPosition - currentOffset.top;
226					$('html').bind('mouseup', onStopDrag).bind('mousemove', updateScroll);
227					if ($.browser.msie) {
228						$('html').bind('dragstart', ignoreNativeDrag).bind('selectstart', ignoreNativeDrag);
229					}
230					return false;
231				};
232				var onStopDrag = function()
233				{
234					$('html').unbind('mouseup', onStopDrag).unbind('mousemove', updateScroll);
235					dragMiddle = percentInView*paneHeight/2;
236					if ($.browser.msie) {
237						$('html').unbind('dragstart', ignoreNativeDrag).unbind('selectstart', ignoreNativeDrag);
238					}
239				};
240				var positionDrag = function(destY)
241				{
242					destY = destY < 0 ? 0 : (destY > maxY ? maxY : destY);
243					dragPosition = destY;
244					$drag.css({'top':destY+'px'});
245					var p = destY / maxY;
246					$pane.css({'top':((paneHeight-contentHeight)*p) + 'px'});
247					$this.trigger('scroll');
248					if (settings.showArrows) {
249						$upArrow[destY == 0 ? 'addClass' : 'removeClass']('disabled');
250						$downArrow[destY == maxY ? 'addClass' : 'removeClass']('disabled');
251					}
252				};
253				var updateScroll = function(e)
254				{
255					positionDrag(getPos(e, 'Y') - currentOffset.top - dragMiddle);
256				};
257				
258				var dragH = Math.max(Math.min(percentInView*(paneHeight-settings.arrowSize*2), settings.dragMaxHeight), settings.dragMinHeight);
259				
260				$drag.css(
261					{'height':dragH+'px'}
262				).bind('mousedown', onStartDrag);
263				
264				var trackScrollInterval;
265				var trackScrollInc;
266				var trackScrollMousePos;
267				var doTrackScroll = function()
268				{
269					if (trackScrollInc > 8 || trackScrollInc%4==0) {
270						positionDrag((dragPosition - ((dragPosition - trackScrollMousePos) / 2)));
271					}
272					trackScrollInc ++;
273				};
274				var onStopTrackClick = function()
275				{
276					clearInterval(trackScrollInterval);
277					$('html').unbind('mouseup', onStopTrackClick).unbind('mousemove', onTrackMouseMove);
278				};
279				var onTrackMouseMove = function(event)
280				{
281					trackScrollMousePos = getPos(event, 'Y') - currentOffset.top - dragMiddle;
282				};
283				var onTrackClick = function(event)
284				{
285					initDrag();
286					onTrackMouseMove(event);
287					trackScrollInc = 0;
288					$('html').bind('mouseup', onStopTrackClick).bind('mousemove', onTrackMouseMove);
289					trackScrollInterval = setInterval(doTrackScroll, 100);
290					doTrackScroll();
291				};
292				
293				$track.bind('mousedown', onTrackClick);
294				
295				$container.bind(
296					'mousewheel',
297					function (event, delta) {
298						initDrag();
299						ceaseAnimation();
300						var d = dragPosition;
301						positionDrag(dragPosition - delta * mouseWheelMultiplier);
302						var dragOccured = d != dragPosition;
303						return false;
304					}
305				);
306
307				var _animateToPosition;
308				var _animateToInterval;
309				function animateToPosition()
310				{
311					var diff = (_animateToPosition - dragPosition) / settings.animateStep;
312					if (diff > 1 || diff < -1) {
313						positionDrag(dragPosition + diff);
314					} else {
315						positionDrag(_animateToPosition);
316						ceaseAnimation();
317					}
318				}
319				var ceaseAnimation = function()
320				{
321					if (_animateToInterval) {
322						clearInterval(_animateToInterval);
323						delete _animateToPosition;
324					}
325				};
326				var scrollTo = function(pos, preventAni)
327				{
328					if (typeof pos == "string") {
329						$e = $(pos, $this);
330						if (!$e.length) return;
331						pos = $e.offset().top - $this.offset().top;
332					}
333					$container.scrollTop(0);
334					ceaseAnimation();
335					var destDragPosition = -pos/(paneHeight-contentHeight) * maxY;
336					if (preventAni || !settings.animateTo) {
337						positionDrag(destDragPosition);
338					} else {
339						_animateToPosition = destDragPosition;
340						_animateToInterval = setInterval(animateToPosition, settings.animateInterval);
341					}
342				};
343				$this[0].scrollTo = scrollTo;
344				
345				$this[0].scrollBy = function(delta)
346				{
347					var currentPos = -parseInt($pane.css('top')) || 0;
348					scrollTo(currentPos + delta);
349				};
350				
351				initDrag();
352				
353				scrollTo(-currentScrollPosition, true);
354			
355				// Deal with it when the user tabs to a link or form element within this scrollpane
356				$('*', this).bind(
357					'focus',
358					function(event)
359					{
360						var $e = $(this);
361						
362						// loop through parents adding the offset top of any elements that are relatively positioned between
363						// the focused element and the jScrollPaneContainer so we can get the true distance from the top
364						// of the focused element to the top of the scrollpane...
365						var eleTop = 0;
366						
367						while ($e[0] != $this[0]) {
368							eleTop += $e.position().top;
369							$e = $e.offsetParent();
370						}
371						
372						var viewportTop = -parseInt($pane.css('top')) || 0;
373						var maxVisibleEleTop = viewportTop + paneHeight;
374						var eleInView = eleTop > viewportTop && eleTop < maxVisibleEleTop;
375						if (!eleInView) {
376							var destPos = eleTop - settings.scrollbarMargin;
377							if (eleTop > viewportTop) { // element is below viewport - scroll so it is at bottom.
378								destPos += $(this).height() + 15 + settings.scrollbarMargin - paneHeight;
379							}
380							scrollTo(destPos);
381						}
382					}
383				)
384				
385				
386				if (location.hash) {
387					scrollTo(location.hash);
388				}
389				
390				// use event delegation to listen for all clicks on links and hijack them if they are links to
391				// anchors within our content...
392				$(document).bind(
393					'click',
394					function(e)
395					{
396						$target = $(e.target);
397						if ($target.is('a')) {
398							var h = $target.attr('href');
399							if (h.substr(0, 1) == '#') {
400								scrollTo(h);
401							}
402						}
403					}
404				);
405				
406				$.jScrollPaneCusel.active.push($this[0]);
407				
408			} else {
409				$this.css(
410					{
411						'height':paneHeight+'px',
412						'width':paneWidth-this.originalSidePaddingTotal+'px',
413						'padding':this.originalPadding
414					}
415				);
416				// remove from active list?
417				$this.parent().unbind('mousewheel');
418			}
419			
420		}
421	)
422};
423$.fn.jScrollPaneRemoveCusel = function()
424{
425	$(this).each(function()
426	{
427		$this = $(this);
428		var $c = $this.parent();
429		if ($c.is('.jScrollPaneContainer')) {
430			$this.css(
431				{
432					'top':'',
433					'height':'',
434					'width':'',
435					'padding':'',
436					'overflow':'',
437					'position':''
438				}
439			);
440			$this.attr('style', $this.data('originalStyleTag'));
441			$c.after($this).remove();
442		}
443	});
444}
445
446$.fn.jScrollPaneCusel.defaults = {
447	scrollbarWidth : 10,
448	scrollbarMargin : 5,
449	wheelSpeed : 18,
450	showArrows : false,
451	arrowSize : 0,
452	animateTo : false,
453	dragMinHeight : 1,
454	dragMaxHeight : 99999,
455	animateInterval : 100,
456	animateStep: 3,
457	maintainPosition: true,
458	scrollbarOnLeft: false,
459	reinitialiseOnImageLoad: false
460};
461
462// clean up the scrollTo expandos
463$(window)
464	.bind('unload', function() {
465		var els = $.jScrollPaneCusel.active; 
466		for (var i=0; i<els.length; i++) {
467			els[i].scrollTo = els[i].scrollBy = null;
468		}
469	}
470);
471
472})(jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.