Procházet zdrojové kódy

more enhancements for scrolling in agenda view
- less flicker when initially switching to agenda view
- when switching back to agenda view, maintains scroll position
- when window is resized, maintains scroll position
- fixes for Opera

Adam Shaw před 16 roky
rodič
revize
9bb6d15fe3
2 změnil soubory, kde provedl 28 přidání a 22 odebrání
  1. 16 13
      src/agenda.js
  2. 12 9
      src/main.js

+ 16 - 13
src/agenda.js

@@ -75,6 +75,7 @@ function Agenda(element, options, methods) {
 		colCnt,
 		axisWidth, colWidth, slotHeight,
 		viewWidth, viewHeight,
+		savedScrollTop,
 		cachedEvents=[],
 		daySegmentContainer,
 		slotSegmentContainer,
@@ -95,7 +96,12 @@ function Agenda(element, options, methods) {
 		clearEvents: clearEvents,
 		setHeight: setHeight,
 		setWidth: setWidth,
-		shown: resetScroll,
+		beforeHide: function() {
+			savedScrollTop = body.scrollTop();
+		},
+		afterShow: function() {
+			body.scrollTop(savedScrollTop);
+		},
 		defaultEventEnd: function(event) {
 			var start = cloneDate(event.start);
 			if (event.allDay) {
@@ -265,19 +271,16 @@ function Agenda(element, options, methods) {
 		var d0 = zeroDate(),
 			scrollDate = cloneDate(d0);
 		scrollDate.setHours(options.firstHour);
-		var go = function() {
-			body.scrollTop(timePosition(d0, scrollDate) + 1); // +1 for the border
-				// TODO: +1 doesn't apply when firstHour=0
-		}
-		//if ($.browser.opera) {
-			setTimeout(go, 0); // opera 10 (and earlier?) needs this
-		//}else{
-		//	go();
-		//}
+		var top = timePosition(d0, scrollDate) + 1, // +1 for the border
+			scroll = function() {
+				body.scrollTop(top);
+			};
+		scroll();
+		setTimeout(scroll, 0); // overrides any previous scroll state made by the browser
 	}
 	
 	
-	function setHeight(height, dontResetScroll) {
+	function setHeight(height, dateChanged) {
 		viewHeight = height;
 		slotTopCache = {};
 		
@@ -290,7 +293,7 @@ function Agenda(element, options, methods) {
 			height: height
 		});
 		
-		if (!dontResetScroll) {
+		if (dateChanged) {
 			resetScroll();
 		}
 	}
@@ -456,7 +459,7 @@ function Agenda(element, options, methods) {
 				bindDaySegHandlers,
 				modifiedEventId
 			);
-			setHeight(viewHeight, true); // might have pushed the body down, so resize
+			setHeight(viewHeight); // might have pushed the body down, so resize
 		}
 	}
 	

+ 12 - 9
src/main.js

@@ -192,20 +192,20 @@ $.fn.fullCalendar = function(options) {
 					newViewElement;
 					
 				if (oldView) {
+					if (oldView.beforeHide) {
+						oldView.beforeHide(); // called before changing min-height/overflow. if called after, scroll state is reset (in Opera)
+					}
 					if (oldView.eventsChanged) {
 						eventsDirty();
 						oldView.eventDirty = oldView.eventsChanged = false;
 					}
-					setMinHeight(content, content.height()); // needs to be first
+					setMinHeight(content, content.height()); // needs to be called before setting overflow
 					content.css('overflow', 'hidden');
 					oldView.element.hide();
 				}
 				
 				if (viewInstances[v]) {
 					(view = viewInstances[v]).element.show();
-					if (view.shown) {
-						view.shown();
-					}
 				}else{
 					view = viewInstances[v] = $.fullCalendar.views[v](
 						newViewElement = $("<div class='fc-view fc-view-" + v + "' style='position:absolute'/>").appendTo(content),
@@ -225,9 +225,12 @@ $.fn.fullCalendar = function(options) {
 					newViewElement.css('position', 'relative');
 				}
 				if (oldView) {
-					content.css('overflow', ''); // needs to be first
+					content.css('overflow', ''); // needs to be called before setting min-height
 					setMinHeight(content, 0);
 				}
+				if (!newViewElement && view.afterShow) {
+					view.afterShow(); // called after setting min-height/overflow, so in final scroll state (for Opera)
+				}
 				
 				ignoreWindowResize--;
 			}
@@ -239,7 +242,7 @@ $.fn.fullCalendar = function(options) {
 				
 				if (!view.start || inc || date < view.start || date >= view.end) {
 					view.render(date, inc || 0); // responsible for clearing events
-					setSize();
+					setSize(true);
 					if (!eventStart || view.visStart < eventStart || view.visEnd > eventEnd) {
 						fetchEvents(function(events) {
 							ignoreWindowResize++;
@@ -742,10 +745,10 @@ $.fn.fullCalendar = function(options) {
 		}
 		
 		
-		function setSize() {
+		function setSize(dateChanged) {
 			ignoreWindowResize++;
-			view.setHeight(suggestedViewHeight);
-			view.setWidth(content.width());
+			view.setHeight(suggestedViewHeight, dateChanged);
+			view.setWidth(content.width(), dateChanged);
 			ignoreWindowResize--;
 		}